commit c2516b73ac8fd96ef25405154d55265e52081ab7 Author: KynixInHK Date: Wed Oct 30 17:23:51 2024 +0800 新增深度學習 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee73dee --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.venv +cifar-10/**/* +cifar-10 +data \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..167e747 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,66 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/learn-pytorch.iml b/.idea/learn-pytorch.iml new file mode 100644 index 0000000..2c80e12 --- /dev/null +++ b/.idea/learn-pytorch.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8a9ff3c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..e69f017 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/other.xml b/.idea/other.xml new file mode 100644 index 0000000..2e75c2e --- /dev/null +++ b/.idea/other.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/classification.py b/classification.py new file mode 100644 index 0000000..d27a21d --- /dev/null +++ b/classification.py @@ -0,0 +1,130 @@ +import torch +import torchvision +import torchvision.transforms as transforms +from torch import optim +from torch.utils.data import Dataset +import torch.nn as nn +import torch.nn.functional as F + +data_path = "data/" + +device = torch.device("cuda" if torch.cuda.is_available() else "mps" if torch.mps.is_available() else "cpu") + +transforms = transforms.Compose([ + transforms.ToTensor(), # 將圖像轉換為 Tensor + transforms.Normalize((0.4915, 0.4823, 0.4468), (0.2470, 0.2435, 0.2616)) + # 歸一化,第一個 tuple 代表 CIFAR-10 這個資料集 RGB 三個通道的平均值,第二個 tuple 代表標準差 +]) + +train_dataset = torchvision.datasets.CIFAR10( + root=data_path, + train=True, + download=True, + transform=transforms +) + +test_dataset = torchvision.datasets.CIFAR10( + root=data_path, + train=False, + download=True, + transform=transforms +) + +label_map = { + 0: 0, # 飛機 + 2: 1, # 小鳥 +} + +class_names = ["airplane", "bird"] + +train_dataset = [(img, label_map[label]) for img, label in train_dataset if label in [0, 2]] +test_dataset = [(img, label_map[label]) for img, label in test_dataset if label in [0, 2]] + + +class ModelDataset(Dataset): + def __init__(self, dataset): + self.dataset = dataset + + def __getitem__(self, index): + img, label = self.dataset[index] + return img, label + + def __len__(self): + return len(self.dataset) + + +train_dataset = ModelDataset(train_dataset) +test_dataset = ModelDataset(test_dataset) + +train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True) +test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=True) + +# 宣告模型 +class Net(nn.Module): + def __init__(self, n_chansl=16): + super().__init__() + + self.n_chansl = n_chansl + + self.conv1 = nn.Conv2d(3, n_chansl, kernel_size=3, padding=1) + self.conv1_batchnorm = nn.BatchNorm2d(n_chansl) # 歸一化器,輸入為通道數,輸出為相同的通道數 + self.conv2 = nn.Conv2d(n_chansl, n_chansl // 2, kernel_size=3, padding=1) + self.conv2_batchnorm = nn.BatchNorm2d(n_chansl // 2) + + self.fc1 = nn.Linear(8 * 8 * n_chansl // 2, 32) + self.fc2 = nn.Linear(32, 2) + + def forward(self, x): + out = F.max_pool2d(self.conv1_batchnorm(torch.relu(self.conv1(x))), kernel_size=2) + out = F.max_pool2d(self.conv2_batchnorm(torch.relu(self.conv2(out))), kernel_size=2) + out = out.view(-1, 8 * 8 * self.n_chansl // 2) + out = torch.relu(self.fc1(out)) + out = self.fc2(out) + return out + +model = Net().to(device) + +optimizer = optim.SGD(model.parameters(), lr=1e-2) +loss_fn = nn.CrossEntropyLoss() + +def train(epoch): + global loss + for epoch in range(epoch): + for (image, label) in train_loader: + image = image.to(device) + label = label.to(device) + outputs = model(image) + loss = loss_fn(outputs, label) + + l2_lambda = 0.001 + l2_norm = sum(p.pow(2.0).sum() for p in model.parameters()) + loss = loss + l2_lambda * l2_norm + + optimizer.zero_grad() + loss.backward() + optimizer.step() + + print(f"Epoch {epoch}, Loss {loss}") + + +train(100) + + +def test(): + correct = 0 + total = 0 + with torch.no_grad(): + for (image, label) in test_loader: + image = image.to(device) + label = label.to(device) + outputs = model(image) + _, predicted = torch.max(outputs, dim=1) + total += label.size(0) + correct += (predicted == label).sum().item() + + print(f"Accuracy: {correct / total}") + + +test() + +# torch.save(model.state_dict(), "model/model.pt") diff --git a/linear.py b/linear.py new file mode 100644 index 0000000..28a1e2b --- /dev/null +++ b/linear.py @@ -0,0 +1,97 @@ +# 1. 收集數據 +import torch + +t_c = [0.5, 14.0, 15.0, 28.0, 11.0, 8.0, 3.0, -4.0, 6.0, 13.0, 21.0] +t_u = [35.7, 55.9, 58.2, 81.9, 56.3, 48.9, 33.9, 21.8, 48.4, 60.4, 68.4] + +t_c = torch.tensor(t_c).unsqueeze(1) # 升維,作用是將資料轉化成單個樣本 +t_u = torch.tensor(t_u).unsqueeze(1) + +n_samples = t_u.shape[0] # 樣本量 +n_test = int(n_samples * 0.2) # 測試集數量 + +shuffled_samples = torch.randperm(n_samples) # 隨機化樣本 + +train_indics = shuffled_samples[:-n_test] # 訓練集索引 +test_indics = shuffled_samples[-n_test:] # 測試集索引 + +# 訓練集 +t_u_train = t_u[train_indics] +t_c_train = t_c[train_indics] +# 測試集 +t_u_test = t_u[test_indics] +t_c_test = t_c[test_indics] + +print(t_u_train) +print(t_c_train) +print(t_u_test) +print(t_c_test) + +# 歸一化 +t_u_mean = t_u_train.mean() +t_u_std = t_u_train.std() + +t_u_train_norm = (t_u_train - t_u_mean) / t_u_std +t_u_test_norm = (t_u_test - t_u_mean) / t_u_std + +t_c_mean = t_c_train.mean() +t_c_std = t_c_train.std() + +t_c_train_norm = (t_c_train - t_c_mean) / t_c_std +t_c_test_norm = (t_c_test - t_c_mean) / t_c_std + +# 2. 搭建模型 +# import torch.nn as nn +# +# linear_model = nn.Linear(in_features = 1, out_features = 1) # in_features 表示輸入神經元的個數,out_features 表示輸出神經元的個數 + +import torch.nn as nn +from collections import OrderedDict + +# 構建一個多層神經網路,隱藏層有 13 個神經元,輸出層有 1 個神經元 +neural_network = nn.Sequential(OrderedDict([ + ('hidden', nn.Linear(1, 13)), # 隱藏層 + ('hidden_activation', nn.Tanh()), # 隱藏層激勵函數 + ('output', nn.Linear(13, 1)) # 輸出層 +])) + +# 3. 宣告優化器和損失函數 +optimizer = torch.optim.SGD( + neural_network.parameters(), + lr=1e-2 +) + +def loss_fn(t_p, t_c): + return ((t_p - t_c) ** 2).mean() + +# 4. 宣告 train loop +def train_loop(n_epochs, optimizer, model, loss_fun, t_u_train, t_u_test, t_c_train, t_c_test): + for epoch in range(1, n_epochs + 1): + t_p_train = model(t_u_train) + loss_train = loss_fun(t_p_train, t_c_train) + + t_p_test = model(t_u_test) + loss_test = loss_fun(t_p_test, t_c_test) + + optimizer.zero_grad() + loss_train.backward() + optimizer.step() + + if epoch == 1 or epoch % 10 == 0: + print(f'Epoch {epoch}: Training Loss: {loss_train:.4f}') + print(f'Test Loss: {loss_test:.4f}') + +# 5. 開始訓練 +train_loop( + n_epochs = 500, + optimizer = optimizer, + model = neural_network, + loss_fun = loss_fn, + t_u_train = t_u_train_norm, + t_u_test = t_u_test_norm, + t_c_train = t_c_train_norm, + t_c_test = t_c_test_norm +) + +print('output', neural_network(t_u_test_norm) * t_c_std + t_c_mean) +print('val', t_c_test) \ No newline at end of file