| @@ -31,7 +31,7 @@ | |||||
| **num_workers : int** | **num_workers : int** | ||||
| + The number of workers used for loading data. | + The number of workers used for loading data. | ||||
| **criterion : torch.nn.Module** | |||||
| **loss_fn : torch.nn.Module** | |||||
| + The loss function used for training. | + The loss function used for training. | ||||
| **optimizer : torch.nn.Module** | **optimizer : torch.nn.Module** | ||||
| @@ -60,13 +60,13 @@ | |||||
| > ```python | > ```python | ||||
| > # Three necessary component | > # Three necessary component | ||||
| > cls = LeNet5() | > cls = LeNet5() | ||||
| > criterion = nn.CrossEntropyLoss() | |||||
| > loss_fn = nn.CrossEntropyLoss() | |||||
| > optimizer = torch.optim.Adam(cls.parameters()) | > optimizer = torch.optim.Adam(cls.parameters()) | ||||
| > | > | ||||
| > # Initialize base_model | > # Initialize base_model | ||||
| > base_model = BasicModel( | > base_model = BasicModel( | ||||
| > cls, | > cls, | ||||
| > criterion, | |||||
| > loss_fn, | |||||
| > optimizer, | > optimizer, | ||||
| > torch.device("cuda:0"), | > torch.device("cuda:0"), | ||||
| > batch_size=32, | > batch_size=32, | ||||
| @@ -39,11 +39,11 @@ For a PyTorch-based neural network, we first need to encapsulate it within a ``B | |||||
| import torchvision | import torchvision | ||||
| cls = torchvision.models.resnet18(pretrained=True) | cls = torchvision.models.resnet18(pretrained=True) | ||||
| # criterion and optimizer are used for training | |||||
| criterion = torch.nn.CrossEntropyLoss() | |||||
| # loss_fn and optimizer are used for training | |||||
| loss_fn = torch.nn.CrossEntropyLoss() | |||||
| optimizer = torch.optim.Adam(cls.parameters()) | optimizer = torch.optim.Adam(cls.parameters()) | ||||
| base_model = BasicNN(cls, criterion, optimizer) | |||||
| base_model = BasicNN(cls, loss_fn, optimizer) | |||||
| model = ABLModel(base_model) | model = ABLModel(base_model) | ||||
| Besides ``fit`` and ``predict``, ``BasicNN`` also implements the following methods: | Besides ``fit`` and ``predict``, ``BasicNN`` also implements the following methods: | ||||
| @@ -84,17 +84,17 @@ To build the machine learning part, we need to wrap our machine learning model i | |||||
| # The number of pseudo labels is 10 | # The number of pseudo labels is 10 | ||||
| cls = LeNet5(num_classes=10) | cls = LeNet5(num_classes=10) | ||||
| Aside from the network, we need to define a criterion, an optimizer, and a device so as to create a ``BasicNN`` object. This class implements ``fit``, ``predict``, ``predict_proba`` and several other methods to enable the PyTorch-based neural network to work as a scikit-learn model. | |||||
| Aside from the network, we need to define a loss_fn, an optimizer, and a device so as to create a ``BasicNN`` object. This class implements ``fit``, ``predict``, ``predict_proba`` and several other methods to enable the PyTorch-based neural network to work as a scikit-learn model. | |||||
| .. code:: python | .. code:: python | ||||
| import torch | import torch | ||||
| from abl.learning import BasicNN | from abl.learning import BasicNN | ||||
| criterion = torch.nn.CrossEntropyLoss() | |||||
| loss_fn = torch.nn.CrossEntropyLoss() | |||||
| optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99)) | optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99)) | ||||
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | ||||
| base_model = BasicNN(cls, criterion, optimizer, device) | |||||
| base_model = BasicNN(cls, loss_fn, optimizer, device) | |||||
| .. code:: python | .. code:: python | ||||
| @@ -32,14 +32,14 @@ class HEDBridge(SimpleBridge): | |||||
| num_classes=len(self.reasoner.kb.pseudo_label_list) | num_classes=len(self.reasoner.kb.pseudo_label_list) | ||||
| ) | ) | ||||
| device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") | device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") | ||||
| criterion = torch.nn.MSELoss() | |||||
| loss_fn = torch.nn.MSELoss() | |||||
| optimizer = torch.optim.RMSprop( | optimizer = torch.optim.RMSprop( | ||||
| cls_autoencoder.parameters(), lr=0.001, alpha=0.9, weight_decay=1e-6 | cls_autoencoder.parameters(), lr=0.001, alpha=0.9, weight_decay=1e-6 | ||||
| ) | ) | ||||
| pretrain_model = BasicNN( | pretrain_model = BasicNN( | ||||
| cls_autoencoder, | cls_autoencoder, | ||||
| criterion, | |||||
| loss_fn, | |||||
| optimizer, | optimizer, | ||||
| device, | device, | ||||
| save_interval=1, | save_interval=1, | ||||
| @@ -157,7 +157,7 @@ | |||||
| "source": [ | "source": [ | ||||
| "# Build necessary components for BasicNN\n", | "# Build necessary components for BasicNN\n", | ||||
| "cls = SymbolNet(num_classes=4)\n", | "cls = SymbolNet(num_classes=4)\n", | ||||
| "criterion = nn.CrossEntropyLoss()\n", | |||||
| "loss_fn = nn.CrossEntropyLoss()\n", | |||||
| "optimizer = torch.optim.RMSprop(cls.parameters(), lr=0.001, weight_decay=1e-6)\n", | "optimizer = torch.optim.RMSprop(cls.parameters(), lr=0.001, weight_decay=1e-6)\n", | ||||
| "# optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))\n", | "# optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))\n", | ||||
| "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")" | "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")" | ||||
| @@ -173,7 +173,7 @@ | |||||
| "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | ||||
| "base_model = BasicNN(\n", | "base_model = BasicNN(\n", | ||||
| " cls,\n", | " cls,\n", | ||||
| " criterion,\n", | |||||
| " loss_fn,\n", | |||||
| " optimizer,\n", | " optimizer,\n", | ||||
| " device,\n", | " device,\n", | ||||
| " batch_size=32,\n", | " batch_size=32,\n", | ||||
| @@ -95,7 +95,7 @@ | |||||
| "# Initialize necessary component for machine learning part\n", | "# Initialize necessary component for machine learning part\n", | ||||
| "cls = SymbolNet(num_classes=len(kb.pseudo_label_list), image_size=(45, 45, 1))\n", | "cls = SymbolNet(num_classes=len(kb.pseudo_label_list), image_size=(45, 45, 1))\n", | ||||
| "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", | ||||
| "criterion = nn.CrossEntropyLoss()\n", | |||||
| "loss_fn = nn.CrossEntropyLoss()\n", | |||||
| "optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))" | "optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))" | ||||
| ] | ] | ||||
| }, | }, | ||||
| @@ -109,7 +109,7 @@ | |||||
| "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | ||||
| "base_model = BasicNN(\n", | "base_model = BasicNN(\n", | ||||
| " model=cls,\n", | " model=cls,\n", | ||||
| " criterion=criterion,\n", | |||||
| " loss_fn=loss_fn,\n", | |||||
| " optimizer=optimizer,\n", | " optimizer=optimizer,\n", | ||||
| " device=device,\n", | " device=device,\n", | ||||
| " save_interval=1,\n", | " save_interval=1,\n", | ||||
| @@ -199,7 +199,7 @@ | |||||
| "metadata": {}, | "metadata": {}, | ||||
| "outputs": [], | "outputs": [], | ||||
| "source": [ | "source": [ | ||||
| "bridge.train(train_data, loops=3, segment_size=1000, save_interval=1, save_dir=weights_dir)\n", | |||||
| "bridge.train(train_data, train_data, loops=3, segment_size=1000, save_interval=1, save_dir=weights_dir)\n", | |||||
| "bridge.test(test_data)" | "bridge.test(test_data)" | ||||
| ] | ] | ||||
| } | } | ||||
| @@ -50,7 +50,7 @@ | |||||
| "source": [ | "source": [ | ||||
| "# Build necessary components for BasicNN\n", | "# Build necessary components for BasicNN\n", | ||||
| "cls = LeNet5(num_classes=10)\n", | "cls = LeNet5(num_classes=10)\n", | ||||
| "criterion = nn.CrossEntropyLoss()\n", | |||||
| "loss_fn = nn.CrossEntropyLoss()\n", | |||||
| "optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))\n", | "optimizer = torch.optim.Adam(cls.parameters(), lr=0.001, betas=(0.9, 0.99))\n", | ||||
| "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")" | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")" | ||||
| ] | ] | ||||
| @@ -65,7 +65,7 @@ | |||||
| "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | "# The function of BasicNN is to wrap NN models into the form of an sklearn estimator\n", | ||||
| "base_model = BasicNN(\n", | "base_model = BasicNN(\n", | ||||
| " cls,\n", | " cls,\n", | ||||
| " criterion,\n", | |||||
| " loss_fn,\n", | |||||
| " optimizer,\n", | " optimizer,\n", | ||||
| " device,\n", | " device,\n", | ||||
| " batch_size=32,\n", | " batch_size=32,\n", | ||||
| @@ -66,7 +66,7 @@ class SymbolNet(nn.Module): | |||||
| num_features = 64 * (image_size[0] // 4 - 1) * (image_size[1] // 4 - 1) | num_features = 64 * (image_size[0] // 4 - 1) * (image_size[1] // 4 - 1) | ||||
| self.fc1 = nn.Sequential(nn.Linear(num_features, 120), nn.ReLU()) | self.fc1 = nn.Sequential(nn.Linear(num_features, 120), nn.ReLU()) | ||||
| self.fc2 = nn.Sequential(nn.Linear(120, 84), nn.ReLU()) | self.fc2 = nn.Sequential(nn.Linear(120, 84), nn.ReLU()) | ||||
| self.fc3 = nn.Sequential(nn.Linear(84, num_classes), nn.Softmax(dim=1)) | |||||
| self.fc3 = nn.Sequential(nn.Linear(84, num_classes)) | |||||
| def forward(self, x): | def forward(self, x): | ||||
| x = self.conv1(x) | x = self.conv1(x) | ||||
| @@ -44,18 +44,18 @@ class LeNet5(nn.Module): | |||||
| @pytest.fixture | @pytest.fixture | ||||
| def basic_nn_instance(): | def basic_nn_instance(): | ||||
| model = LeNet5() | model = LeNet5() | ||||
| criterion = nn.CrossEntropyLoss() | |||||
| loss_fn = nn.CrossEntropyLoss() | |||||
| optimizer = optim.Adam(model.parameters()) | optimizer = optim.Adam(model.parameters()) | ||||
| return BasicNN(model, criterion, optimizer) | |||||
| return BasicNN(model, loss_fn, optimizer) | |||||
| # Fixture for base_model instance | # Fixture for base_model instance | ||||
| @pytest.fixture | @pytest.fixture | ||||
| def base_model_instance(): | def base_model_instance(): | ||||
| model = LeNet5() | model = LeNet5() | ||||
| criterion = nn.CrossEntropyLoss() | |||||
| loss_fn = nn.CrossEntropyLoss() | |||||
| optimizer = optim.Adam(model.parameters()) | optimizer = optim.Adam(model.parameters()) | ||||
| return BasicNN(model, criterion, optimizer) | |||||
| return BasicNN(model, loss_fn, optimizer) | |||||
| # Fixture for ListData instance | # Fixture for ListData instance | ||||
| @@ -27,7 +27,7 @@ class TestBasicNN(object): | |||||
| def test_initialization(self, basic_nn_instance): | def test_initialization(self, basic_nn_instance): | ||||
| """Test initialization of the BasicNN class""" | """Test initialization of the BasicNN class""" | ||||
| assert basic_nn_instance.model is not None | assert basic_nn_instance.model is not None | ||||
| assert isinstance(basic_nn_instance.criterion, nn.Module) | |||||
| assert isinstance(basic_nn_instance.loss_fn, nn.Module) | |||||
| assert isinstance(basic_nn_instance.optimizer, optim.Optimizer) | assert isinstance(basic_nn_instance.optimizer, optim.Optimizer) | ||||
| def test_training_methods(self, basic_nn_instance, sample_data, sample_data_loader_with_label): | def test_training_methods(self, basic_nn_instance, sample_data, sample_data_loader_with_label): | ||||