VGG
AlexNet Lenet畳み込みに基づいて、コンボリューションカーネルのサイズ、各層の出力チャネルのように数を変化させる、いくつかの層を増加させ、良好な結果を達成したが、思考の単純かつ効果的な方法を提案していない。
VGGを行いますこれは、アイデアの深い学習モデルのために写真の簡単な基本的なビルディングブロックを繰り返すことによって、提案されました。
論文住所:https://arxiv.org/abs/1409.1556
VGG構造を以下に示す。
図に示す異なる層VGGの構造をしばしばvgg16、等vgg19を言われています。
VGG BLOCK
VGGのデザインのアイデア深.vggネットモデルは、モデルの学習能力は非常に有効な手段である改善するために、奥行きモデルを深めることが証明深め、3x3の畳み込みカーネルの連続スタックを介して行われます。
ファンシーマップ見つけることができ、!2つの3x3の連続畳み込み、5x5の受容野と畳み込みは同じであるが、前者は二回非線形変換、一度だけ後者を有している。これは、連続的に、核積層小さな畳み込みを改善しています
モデル研究の主要な機能。加えて、パラメータの数が少ない3x3の5×5よりも2である。(2x3x3 <5×5)
n番目の3x3畳み込みバックコンタクト2x2の畳み込み最大による各層のVGG基本的なビルディング・ブロックをプール。ストライドプール層2層は、このように畳み込み畳み込み、同一の幅と高さ、プール。幅と高さを半分にした後
、私たちは、次のコードを持つことができます。
def make_layers(in_channels,cfg):
layers = []
previous_channel = in_channels #上一层的输出的channel数量
for v in cfg:
if v == 'M':
layers.append(nn.MaxPool2d(kernel_size=2,stride=2))
else:
layers.append(nn.Conv2d(previous_channel,v,kernel_size=3,padding=1))
layers.append(nn.ReLU())
previous_channel = v
conv = nn.Sequential(*layers)
return conv
cfgs = {
'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}
CFGS VGG画定するように代わっのvgg11に「A」のように、異なるモデルの構造。図は、チャネルコンボリューションの数を表す。「M」代表Maxpool
私たちは、モデルの定義を与えることができます
class VGG(nn.Module):
def __init__(self,input_channels,cfg,num_classes=10, init_weights=True):
super(VGG, self).__init__()
self.conv = make_layers(input_channels,cfg) # torch.Size([1, 512, 7, 7])
self.fc = nn.Sequential(
nn.Linear(512*7*7,4096),
nn.ReLU(),
nn.Linear(4096,4096),
nn.ReLU(),
nn.Linear(4096,num_classes)
)
def forward(self, img):
feature = self.conv(img)
output = self.fc(feature.view(img.shape[0], -1))
return output
畳み込み符号層の出力は、以下の試験により得られます
# conv = make_layers(1,cfgs['A'])
# X = torch.randn((1,1,224,224))
# out = conv(X)
# #print(out.shape)
データのロード
batch_size,num_workers=4,4
train_iter,test_iter = learntorch_utils.load_data(batch_size,num_workers,resize=224)
ここBATCH_SIZE 8私の記憶に調整することは十分ではありません...
定義モデル
net = VGG(1,cfgs['A']).cuda()
定義された損失関数
loss = nn.CrossEntropyLoss()
定義のオプティマイザ
opt = torch.optim.Adam(net.parameters(),lr=0.001)
定義された評価関数
def test():
acc_sum = 0
batch = 0
for X,y in test_iter:
X,y = X.cuda(),y.cuda()
y_hat = net(X)
acc_sum += (y_hat.argmax(dim=1) == y).float().sum().item()
batch += 1
#print('acc_sum %d,batch %d' % (acc_sum,batch))
return 1.0*acc_sum/(batch*batch_size)
トレーニング
num_epochs = 3
def train():
for epoch in range(num_epochs):
train_l_sum,batch,acc_sum = 0,0,0
start = time.time()
for X,y in train_iter:
# start_batch_begin = time.time()
X,y = X.cuda(),y.cuda()
y_hat = net(X)
acc_sum += (y_hat.argmax(dim=1) == y).float().sum().item()
l = loss(y_hat,y)
opt.zero_grad()
l.backward()
opt.step()
train_l_sum += l.item()
batch += 1
mean_loss = train_l_sum/(batch*batch_size) #计算平均到每张图片的loss
start_batch_end = time.time()
time_batch = start_batch_end - start
print('epoch %d,batch %d,train_loss %.3f,time %.3f' %
(epoch,batch,mean_loss,time_batch))
print('***************************************')
mean_loss = train_l_sum/(batch*batch_size) #计算平均到每张图片的loss
train_acc = acc_sum/(batch*batch_size) #计算训练准确率
test_acc = test() #计算测试准确率
end = time.time()
time_per_epoch = end - start
print('epoch %d,train_loss %f,train_acc %f,test_acc %f,time %f' %
(epoch + 1,mean_loss,train_acc,test_acc,time_per_epoch))
train()
4G的GTX 1050显卡,训练一个epoch大概一个多小时.
完整代码:https://github.com/sdu2011/learn_pytorch