AE自动编码器代码
博主的其他平臺:博客園
自動編碼器的結構
自動編碼器包括編碼器和解碼器。編碼器對編碼,解碼器解碼,作用跟主成分分析PCA類似,效果更好。編碼器可以將高維度降到一維或其他維度。解碼器進行解碼,載跟原始數據對比計算損失函數。
實際我們只使用到編碼器的輸出,也就是降維后的特征,然后送入監督學習訓練模型。
下面的代碼是用編碼器將fashion-mnsit降到一維,然后在感知機上訓練分類模型。
import torch from torch import nn from torch.utils.data import DataLoader from torchvision import transforms, datasetsnp.random.seed(123) torch.manual_seed(123)LR = 0.0001 #編碼器輸出潛在向量的長度 HIDDEN_SIZE = 128 epochs = 20#如果有gpu,就調用gpu device = torch.device("cuda" if torch.cuda.is_available() else "cpu")train_dataset = datasets.FashionMNIST('./data/', True, transforms.ToTensor(), download=False) test_dataset = datasets.FashionMNIST('./data/', False, transforms.ToTensor()) train_loader = DataLoader(train_dataset, 256, True) test_loader = DataLoader(test_dataset, 256, False)#定義感知機,用于分類 num_inputs, num_outputs, num_hiddens = HIDDEN_SIZE, 10, 256 mlp = nn.Sequential(nn.Linear(num_inputs, num_hiddens),nn.ReLU(),nn.Linear(num_hiddens, num_outputs),).to(device)#定義自編碼器AE class AutoEncoder(nn.Module):def __init__(self):super(AutoEncoder, self).__init__()self.en_conv = nn.Sequential(nn.Conv2d(1, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.Conv2d(16, 32, 4, 2, 1),nn.BatchNorm2d(32),nn.Tanh(),nn.Conv2d(32, 16, 3, 1, 1),nn.BatchNorm2d(16),nn.Tanh())self.en_fc = nn.Linear(16*7*7, HIDDEN_SIZE)self.de_fc = nn.Linear(HIDDEN_SIZE, 16*7*7)self.de_conv = nn.Sequential(nn.ConvTranspose2d(16, 16, 4, 2, 1),nn.BatchNorm2d(16),nn.Tanh(),nn.ConvTranspose2d(16, 1, 4, 2, 1),nn.Sigmoid())def forward(self, x):en = self.en_conv(x)code = self.en_fc(en.view(en.size(0), -1))de = self.de_fc(code)decoded = self.de_conv(de.view(de.size(0), 16, 7, 7))return code, decoded#實例化模型,送到device net = AutoEncoder().to(device)#編碼器訓練 def AutoEncoder_train():#開啟模式net.train()#定義自編碼器的優化器和損失函數optimizer = torch.optim.Adam(net.parameters(), lr=LR,weight_decay=5e-6)loss_f = nn.MSELoss()#訓練for epoch in range(1, epochs+1):for step, (data, label) in enumerate(train_loader):data = data.to(device)net.zero_grad()code, decoded = net(data)loss = loss_f(decoded, data)loss.backward()optimizer.step()print('AutoEncoder epoch [%d/%d] loss:%.4f'%(epoch, epochs, loss))#開啟預測模式,使每次預測結果都是確定性的net.eval()#利用編碼器得到的特征訓練感知機 def train():#訓練自編碼器AutoEncoder_train()#訓練mlpprint('\nmlp training....................\n')#定義感知機的優化器和損失函數optimizer = torch.optim.Adam(mlp.parameters(), lr=LR)loss = torch.nn.CrossEntropyLoss()#訓練mlpfor epoch in range(1, epochs+1):#啟動訓練模式mlp.train()for step, (data, label) in enumerate(train_loader):data = data.to(device)label = label.to(device)mlp.zero_grad()#利用編碼器輸出的向量作為提取特征進行訓練模型code, decoded = net(data)output = mlp(code)l = loss(output, label)l.backward()optimizer.step()print('mlp : eoch: [%d/%d], '%(epoch, epochs), end='')#測試本次epoch后的訓練集精度和損失test(test_loader)#測試感知機的精度 def test(data_loader):#開啟模型預測模式mlp.eval()#定義交叉熵損失函數loss = torch.nn.CrossEntropyLoss()acc_sum, n, loss_sum = 0, 0, 0.0for step, (data, label) in enumerate(data_loader):data = data.to(device)label = label.to(device)code, decoded = net(data)output = mlp(code)l = loss(output, label)#計算預測精度和損失acc_sum += (output.argmax(dim=1)==label).float().sum().item()n += label.shape[0]loss_sum +=lprint('acc:%.2f%% loss:%.4f' %(100*acc_sum/n, loss_sum/(step+1)))if __name__ == '__main__':train()print('模型的測試精度: ', end='')test(test_loader)運行結果入下:
總結
- 上一篇: kaggle和colab入门
- 下一篇: RNN图