0.前言
打算将centerloss移植到人脸的识别上,数据集30人,3000左右的图片
1.实验
1.resnet18+finetuning
Epoch 0/9
----------
train Loss 0.3178 Acc: 0.2627
val Loss 0.2674 Acc: 0.4140
Epoch 1/9
----------
train Loss 0.2228 Acc: 0.4272
val Loss 0.1230 Acc: 0.6579
Epoch 2/9
----------
train Loss 0.1787 Acc: 0.5164
val Loss 0.0783 Acc: 0.7754
Epoch 3/9
----------
train Loss 0.1484 Acc: 0.5803
val Loss 0.0725 Acc: 0.7912
Epoch 4/9
----------
train Loss 0.1384 Acc: 0.6166
val Loss 0.0774 Acc: 0.7825
Epoch 5/9
----------
train Loss 0.1282 Acc: 0.6359
val Loss 0.0802 Acc: 0.7860
Epoch 6/9
----------
train Loss 0.1198 Acc: 0.6698
val Loss 0.0466 Acc: 0.8632
Epoch 7/9
----------
train Loss 0.0838 Acc: 0.7632
val Loss 0.0256 Acc: 0.9281
Epoch 8/9
----------
train Loss 0.0751 Acc: 0.7777
val Loss 0.0218 Acc: 0.9456
Epoch 9/9
----------
train Loss 0.0661 Acc: 0.8130
val Loss 0.0224 Acc: 0.9439
Training complete in 35m 16s
Best val Acc: 0.945614
2.简单三层mnistnet(32*7*7-->200-—》30)
出现过拟合,trainACC达到100%,test达到85%.速度很快
3.简单三层mnistnet(32*7*7-->2-—》30)
train和test达到9%左右,看来全连接层大小影响很大.
4.centerlos+softmaxloss(128*3*3->2_-》30)
权重为0.1,30个epoch acc达到12%
权重为1.5, acc在10%左右,变化不大。
5.centerlos+softmaxloss(128*3*3->10-》30)
权重0.1,30个epoch后 acc达到30%,有一定提升
6.centerlos+softmaxloss(128*3*3->50-》30)
仅采用softmax,20个epoch后, acc达到83%,lossloss达到0.05左右train的ACC接近0.98,过拟合。
Test Loss: 0.058294, Acc: 0.826316
epoch 20
Train Loss: 0.003819, Acc: 0.979069
centerlos+softmaxloss 经过100个epoch,跑到79%的acc。180个epoc后达到82.6%,效果不大。
Predicting Epoch: 178
Validation accuracy: 83.6842105263%
Training Epoch: 179
Train Loss: 0.002816
Predicting Epoch: 179
Validation accuracy: 82.6315789474%
Training Epoch: 180
代码: 可看 https://blog.csdn.net/sinat_37787331/article/details/80296964
import torch
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision
from torchvision import transforms
import torch.nn.functional as F
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import matplotlib.patheffects as PathEffects
from centerLoss import CenterLoss
import torch.optim.lr_scheduler as lr_scheduler
import matplotlib.cm as cm
'''
trainset = torchvision.datasets.MNIST(root='../data', train=True, transform=transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
))
testset = torchvision.datasets.MNIST(root='../data', train=False, transform=transforms.Compose(
[transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]
))
train_loader = Data.DataLoader(dataset=trainset, batch_size=128, shuffle=True, num_workers=4)
test_loader = Data.DataLoader(dataset=testset, batch_size=128, shuffle=True, num_workers=4)
'''
train_data = torchvision.datasets.ImageFolder('/home/syj/Documents/datas/casia/train',
transform=transforms.Compose([
transforms.Resize(28),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]))
train_loader = Data.DataLoader(dataset=train_data, batch_size=40, shuffle=True)
test_data = torchvision.datasets.ImageFolder('/home/syj/Documents/datas/casia/val',
transform=transforms.Compose([
transforms.Resize(28),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]))
test_loader = Data.DataLoader(dataset=test_data, batch_size=40, shuffle=True)
train_loss = []
test_acc = []
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.extract = torch.nn.Sequential(
torch.nn.Linear(784, 512),
torch.nn.PReLU(),
torch.nn.Linear(512, 256),
torch.nn.PReLU(),
torch.nn.Linear(256, 128),
torch.nn.PReLU(),
torch.nn.Linear(128, 64),
torch.nn.PReLU(),
torch.nn.Linear(64, 32),
torch.nn.PReLU(),
torch.nn.Linear(32, 4),
)
self.predict = torch.nn.Sequential(
torch.nn.PReLU(),
torch.nn.Linear(4, 10),
)
def forward(self, x):
feature = self.extract(x.view(-1, 784))
pred = F.log_softmax(self.predict(feature))
return feature, pred
class ConvNet(torch.nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.extract = torch.nn.Sequential(
torch.nn.Conv2d(3, 32, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.Conv2d(32, 32, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.MaxPool2d(2, 2),
torch.nn.Conv2d(32, 64, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.Conv2d(64, 64, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.MaxPool2d(2, 2),
torch.nn.Conv2d(64, 128, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.Conv2d(128, 128, kernel_size=5, padding=2),
torch.nn.PReLU(),
torch.nn.MaxPool2d(2, 2),
)
self.feat = torch.nn.Linear(128*3*3,50)
self.pred = torch.nn.Sequential(
torch.nn.Linear(50, 30)
)
def forward(self, x):
x = self.extract(x)
x = x.view(-1, 128*3*3)
feat = self.feat(x)
pred = F.log_softmax(self.pred(feat))
return feat, pred
#model = Net().cuda()
model = ConvNet().cuda()
optimizer4nn = torch.optim.SGD(model.parameters(), lr=1e-3, momentum=0.9, weight_decay=0.0005)
scheduler = lr_scheduler.StepLR(optimizer4nn, 20, gamma=0.8)
centerloss = CenterLoss(30, 50, 0.1).cuda()
nllloss = torch.nn.NLLLoss().cuda()
#crossentropy = torch.nn.CrossEntropyLoss().cuda()
optimizer4center = torch.optim.SGD(centerloss.parameters(), lr=0.1)
def train(train_loader, model, epoch):
print("Training Epoch: {}".format(epoch))
model.train()
#running_softmax = 0.0
running_loss = 0.0
for step, (data, target) in enumerate(train_loader):
data = Variable(data).cuda()
target = Variable(target).cuda()
feat, pred = model(data)
loss = nllloss(pred, target) + centerloss(target, feat)
running_loss += loss.data[0]
optimizer4nn.zero_grad()
optimizer4center.zero_grad()
loss.backward()
optimizer4nn.step()
optimizer4center.step()
print('Train Loss: {:.6f}'.format(running_loss / (len(
train_data))))
train_loss.append(running_loss / (len(train_data)))
def test(test_loader, model, epoch):
print("Predicting Epoch: {}".format(epoch))
model.eval()
test_acc = 0
total_pred_label = []
total_target = []
total_feature = []
for step, (data, target) in enumerate(test_loader):
data = Variable(data).cuda()
target = Variable(target).cuda()
feature, pred = model(data)
_, pred_label = pred.max(dim=1)
total_pred_label.append(pred_label.data.cpu())
total_target.append(target.data.cpu())
total_feature.append(feature.data.cpu())
total_pred_label = torch.cat(total_pred_label, dim=0)
total_target = torch.cat(total_target, dim=0)
total_feature = torch.cat(total_feature, dim=0)
precision = torch.sum(total_pred_label == total_target) / float(total_target.shape[0])
acc = precision*100
print("Validation accuracy: {}%".format(precision * 100))
#test_acc.append(acc )
#scatter(total_feature.numpy(), total_target.numpy(), epoch)
'''
def scatter(feat, label, epoch):
plt.ion()
plt.clf()
palette = np.array(sns.color_palette('hls', 10))
ax = plt.subplot(aspect='equal')
# sc = ax.scatter(feat[:, 0], feat[:, 1], lw=0, s=40, c=palette[label.astype(np.int)])
for i in range(10):
plt.plot(feat[label == i, 0], feat[label == i, 1], feat[label == i, 2],'.', c=palette[i])
plt.legend(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], loc='upper right')
ax.axis('tight')
for i in range(10):
xtext, ytext ,ztext= np.median(feat[label == i, :], axis=0)
txt = ax.text(xtext, ytext,str(i), fontsize=18)
txt.set_path_effects([PathEffects.Stroke(linewidth=5, foreground="w"), PathEffects.Normal()])
plt.draw()
plt.savefig('./benchmark/centerloss_{}.png'.format(epoch))
plt.pause(0.001)
'''
for epoch in range(200):
#scheduler.step()
train(train_loader, model, epoch)
test(test_loader, model, epoch)
torch.save(model, '/home/syj/Documents/model/cen-min-50->30s.pkl')
plt.figure()
#plt.subplot(2, 1, 1)
plt.plot(train_loss, lw = 1.5, label = 'train_loss')
#plt.subplot(2, 2, 2)
#plt.plot(test_acc, lw = 1.5, label = 'test_acc')
plt.savefig("min-cen-50->30-0.1s.jpg")
plt.show()