Lecture 033. 模型、损失与公平比较范围 · 实现代码
3. 模型、损失与公平比较范围 · 实现代码
按问题继续
RGB+问题输入、question-only对照、同图换问与同问换图
展开完整实现代码
class VQA(nn.Module):
def __init__(self,visual):
super().__init__();self.visual=visual
self.question=nn.Embedding(len(QUESTIONS),12)
if visual:
self.cnn=nn.Sequential(nn.Conv2d(3,12,3,padding=1),nn.ReLU(),nn.MaxPool2d(2),nn.Conv2d(12,24,3,padding=1),nn.ReLU(),nn.MaxPool2d(2),nn.Flatten(),nn.Linear(24*8*10,64),nn.ReLU())
self.answer=nn.Sequential(nn.Linear(64+12 if visual else 12,64),nn.ReLU(),nn.Linear(64,len(ANSWERS)))
def forward(self,pixels,question_id):
q=self.question(question_id)
features=torch.cat([self.cnn(pixels),q],-1) if self.visual else q
return self.answer(features)
full=VQA(True);question_only=VQA(False)
curve=[]
for label,net in [('image+question',full),('question-only',question_only)]:
optimizer=torch.optim.Adam(net.parameters(),lr=.002)
for epoch in range(28):
order=torch.randperm(Ytr.numel());net.train();loss_sum=0.
for pair_ids in order.split(72):
image_ids=pair_ids//3;qids=pair_ids%3
logits=net(Xtr[image_ids],qids);target=Ytr[image_ids,qids]
loss=F.cross_entropy(logits,target)
optimizer.zero_grad();loss.backward();optimizer.step();loss_sum+=float(loss.detach())*len(pair_ids)
if epoch in [0,5,13,27]:print(label,'epoch',epoch+1,'CE',round(loss_sum/Ytr.numel(),4))
curve.append({'model':label,'epoch':epoch+1,'train_ce':loss_sum/Ytr.numel()})
torch.save(net.state_dict(),OUT/('lab14-'+('visual' if net.visual else 'question-only')+'-weights.pt'))