#CNN
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
import torch
from torch.utils import data
from torch import nn
from torchvision import transforms,datasets
import time
import matplotlib.pyplot as plt
# 使用内置函数下载mnist数据集
# 预处理=>将各种预处理组合在一起
data_tf = transforms.Compose(
[transforms.Grayscale(),
transforms.CenterCrop(128),
transforms.RandomHorizontalFlip(),
transforms.ToTensor()])
train_set = datasets.ImageFolder('./data01/train',transform=data_tf)
test_set = datasets.ImageFolder('./data01/test',transform=data_tf)
train_loader = data.DataLoader(train_set,batch_size=128,num_workers=0,shuffle=True)
test_loader = data.DataLoader(test_set,batch_size=128,num_workers=0,shuffle=False)
# 定义LeNet网络结构
net = nn.Sequential(nn.Conv2d(1,8,kernel_size=5,padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Conv2d(8,16,kernel_size=3,padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Conv2d(16,32,kernel_size=4,padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Conv2d(32,64,kernel_size=3,padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Flatten(),
nn.Linear(64*7*7,72),
nn.Dropout(0.5),
nn.ReLU(inplace=True),
nn.Linear(72,7),
nn.Softmax(dim=1)
)
#网络的初始化
def init_weights(m):
if type(m) == nn.Linear:
nn.init.normal_(m.weight, mean=0, std=0.01)
nn.init.zeros_(m.bias)
if type(m) == nn.Conv2d:
nn.init.normal_(m.weight, mean=0, std=0.1)
nn.init.zeros_(m.bias)
net.apply(init_weights)
'''用于计算准确率的函数'''
def classification_accuracy(net, dataloader):
correct = 0
for X, target in dataloader:
pred = net(X)
prob, pred = pred.max(1)
correct = correct + (pred == target).sum()
return correct.item() / len(dataloader.dataset)
################################################################
'''定义损失函数'''
criterion = nn.NLLLoss()
'''定义优化器'''
'''
optimizer = torch.optim.SGD(net.parameters(), lr=0.1)
nums_epoch = 100
'''
optimizer = torch.optim.Adam(net.parameters(), lr=0.0001, weight_decay=0.0001)
nums_epoch = 400
#################################################################
#####################2.开始训练###############################
#################################################################
train_loss =[]
train_acc = []
test_acc = []
for epoch in range(nums_epoch):
net.train()
time_start = time.time()
for img , y in train_loader:
net.zero_grad()
# 前向传播
pred_y = net(img)
#计算损失函数
loss = criterion(torch.log(pred_y+1e-4), y)
# 反向传播
loss.backward()
optimizer.step()
# 记录误差
train_loss.append(loss)
time_end = time.time()
time_cost = time_end - time_start
net.eval()
#计算训练集上的准确度
tr_acc = classification_accuracy(net, train_loader)
train_acc.append(tr_acc)
#计算测试集上的准确度
te_acc = classification_accuracy(net, test_loader)
test_acc.append(te_acc)
print('Epoch {}: 训练集准确率 {} \n 测试集准确率 {}'.format(epoch+1, tr_acc, te_acc))
print("时间消耗:%s 秒\n"%time_cost)
plt.plot(train_loss)
plt.show()
plt.plot(train_acc)
plt.plot(test_acc)
plt.show()