import copy
import os
import random
import numpy as np
import torch
import torch.nn as nn
from torch import optim
from torch.autograd import Variable
from tqdm import tqdm
from data_process import load_data
import torch.nn.functional as F
from torchvision.models import resnet18
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
def setup_seed(seed):
os.environ['PYTHONHASHSEED'] = str(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
random.seed(seed)
torch.backends.cudnn.deterministic = True
setup_seed(20)
class cnn(nn.Module):
# 重写_init_函数
def __init__(self):
super(cnn, self).__init__()
self.relu = nn.ReLU()
self.sigmoid = nn.Sigmoid()
self.conv1 = nn.Sequential(
nn.Conv2d(
in_channels=3,
out_channels=16,
kernel_size=3,
stride=2,
),
nn.BatchNorm2d(16),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
#
self.conv2 = nn.Sequential(
nn.Conv2d(
in_channels=16,
out_channels=32,
kernel_size=3,
stride=2,
),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
#
self.conv3 = nn.Sequential(
nn.Conv2d(
in_channels=32,
out_channels=64,
kernel_size=3,
stride=2,
),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2),
)
self.fc1 = nn.Linear(3 * 3 * 64, 64)
self.fc2 = nn.Linear(64, 10)
self.out = nn.Linear(10, 2)
# 定义前向传递函数
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
# print(x.size())
x = x.view(x.shape[0], -1)
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
# x = self.sigmoid(self.out(x))
x = self.out(x)
x = F.log_softmax(x, dim=1)
return x
def get_val_loss(model, Val):
model.eval()
criterion = nn.CrossEntropyLoss().to(device)
val_loss = []
for (data, target) in Val:
data, target = Variable(data).to(device), Variable(target.long()).to(device)
output = model(data)
loss = criterion(output, target)
val_loss.append(loss.cpu().item())
return np.mean(val_loss)
def train():
Dtr, Val, Dte = load_data()
print('train...')
epoch_num = 50
best_model = None
min_epochs = 5
min_val_loss = 5
# 初始化模型
model = cnn().to(device)
# 选择优化器以及优化算法
optimizer = optim.Adam(model.parameters(), lr=0.0008)
# 选择损失函数:交叉熵
criterion = nn.CrossEntropyLoss().to(device)
# criterion = nn.BCELoss().to(device)
for epoch in tqdm(range(epoch_num), ascii=True):
train_loss = []
for batch_idx, (data, target) in enumerate(Dtr, 0):
data, target = Variable(data).to(device), Variable(target.long()).to(device)
# target = target.view(target.shape[0], -1)
# print(target)
optimizer.zero_grad()
output = model(data)
# print(output)
loss = criterion(output, target)
loss.backward()
optimizer.step()
train_loss.append(loss.cpu().item())
# validation
val_loss = get_val_loss(model, Val)
model.train()
if epoch + 1 > min_epochs and val_loss < min_val_loss:
min_val_loss = val_loss
best_model = copy.deepcopy(model)
tqdm.write('Epoch {:03d} train_loss {:.5f} val_loss {:.5f}'.format(epoch, np.mean(train_loss), val_loss))
torch.save(best_model.state_dict(), "model/cnn2.pkl")
def test():
Dtr, Val, Dte = load_data()
model = cnn().to(device)
model.load_state_dict(torch.load("model/cnn2.pkl"), False)
model.eval()
total = 0
current = 0
for (data, target) in Dte:
data, target = data.to(device), target.to(device)
outputs = model(data)
predicted = torch.max(outputs.data, 1)[1].data
total += target.size(0)
current += (predicted == target).sum()
print('Accuracy:%d%%' % (100 * current / total))
if __name__ == '__main__':
train()
test()
CNN分类2:网络设置及训练
最新推荐文章于 2023-10-26 22:34:12 发布