首页 > 编程知识 正文

mnist数据集csv格式,卷积神经网络纯python代码

时间:2023-05-05 15:58:47 阅读:149695 作者:4830

上一篇文章介绍了wxdpkq Net的原理和这种网络架构的重要——丢失函数contrastive loss。 用pytorch做一个简单的案例吧。 经过这个案例,我的个人收获达到了以下几点。

wxdpkq Net适用于小数据集。目前,wxdpkq Net用于分类任务。 (如果有朋友知道如何用于拆分或其他任务,很可能会解释WX:cyx645016617 ) wxdpkq Net。 1数据importpandasaspdimportnumpyasnpimportmatplotlib.pyplotaspltimporttorch.nnasnnimporttorch.nn.functional aporttion dataloaderfromsklearn.model _ selectionimporttrain _ test _ split device=' cuda ' if torch.cuda.is _ available () eable

该数据文件为csv格式,第一列为类别,后面的784列实际上好像是28x28的像素值。

划分训练集和验证集,然后把数据转换成28x28的图片

x _ full=data _ train.iloc [ :1: ] y _ full=data _ train.iloc [ :1 ] x _ train,x _ test 1 ).astype(float32 ' ) 255.x_ttape 1).astype('float32 ' )/255.y_train.label.unique ) array ) ([

0t-shirt/top1 trouser2pullove R3 dress 4co at5 sandal6shirt7sneaker8bag9anklebootnp.bincount (y _ train.label.values ),values

Dataset和可视化classmydataset(dataset ) :def_init_ ) self、 构建x_data,y_data ) : self.x _ data=x _ dataself.y _ data=y _ data.label.values def _ len _ (self ) ifnp.random.rand (0.53360 id x2=NP.random.[ self.y _ data==y1 ],1 (else : idx2=NP.random.choice (NP 1 ) img2=self.x_data[idx2[0] ) y2=self.y_data[idx2[0] ) label=0ify1==y2else1returnimg1,y2 else1rrereta 有50%的概率选择两张同种图像,最后输出时,输出这两张图像,再输出一个标签。 此标签为0时,表示两个图像的类别相同,1表示两个图像的类别不同。 这样,模型训练和

损失函数的计算了。

train_dataset = mydataset(x_train,y_train)train_dataloader = DataLoader(dataset = train_dataset,batch_size=8)val_dataset = mydataset(x_test,y_test)val_dataloader = DataLoader(dataset = val_dataset,batch_size=8) for idx,(img1,img2,target) in enumerate(train_dataloader): fig, axs = plt.subplots(2, img1.shape[0], figsize = (12, 6)) for idx,(ax1,ax2) in enumerate(axs.T): ax1.imshow(img1[idx,:,:,0].numpy(),cmap='gray') ax1.set_title('image A') ax2.imshow(img2[idx,:,:,0].numpy(),cmap='gray') ax2.set_title('{}'.format('same' if target[idx]==0 else 'different')) break

这一段的代码就是对一个batch的数据进行一个可视化:

到目前位置应该没有什么问题把,有问题可以联系我讨论交流,WX:cyx645016617.我个人认为从交流中可以快速解决问题和进步。

3 构建模型 class mmydqyg(nn.Module): def __init__(self,z_dimensions=2): super(mmydqyg,self).__init__() self.feature_net = nn.Sequential( nn.Conv2d(1,4,kernel_size=3,padding=1,stride=1), nn.ReLU(inplace=True), nn.BatchNorm2d(4), nn.Conv2d(4,4,kernel_size=3,padding=1,stride=1), nn.ReLU(inplace=True), nn.BatchNorm2d(4), nn.MaxPool2d(2), nn.Conv2d(4,8,kernel_size=3,padding=1,stride=1), nn.ReLU(inplace=True), nn.BatchNorm2d(8), nn.Conv2d(8,8,kernel_size=3,padding=1,stride=1), nn.ReLU(inplace=True), nn.BatchNorm2d(8), nn.MaxPool2d(2), nn.Conv2d(8,1,kernel_size=3,padding=1,stride=1), nn.ReLU(inplace=True) ) self.linear = nn.Linear(49,z_dimensions) def forward(self,x): x = self.feature_net(x) x = x.view(x.shape[0],-1) x = self.linear(x) return x

一个非常简单的卷积网络,输出的向量的维度就是z-dimensions的大小。

def contrastive_loss(pred1,pred2,target): MARGIN = 2 euclidean_dis = F.pairwise_distance(pred1,pred2) target = target.view(-1) loss = (1-target)*torch.pow(euclidean_dis,2) + target * torch.pow(torch.clamp(MARGIN-euclidean_dis,min=0),2) return loss

然后构建了一个contrastive loss的损失函数计算。

4 训练 model = mmydqyg(z_dimensions=8).to(device)# model.load_state_dict(torch.load('../working/saimese.pth'))optimizor = torch.optim.Adam(model.parameters(),lr=0.001) for e in range(10): history = [] for idx,(img1,img2,target) in enumerate(train_dataloader): img1 = img1.to(device) img2 = img2.to(device) target = target.to(device) pred1 = model(img1) pred2 = model(img2) loss = contrastive_loss(pred1,pred2,target) optimizor.zero_grad() loss.backward() optimizor.step() loss = loss.detach().cpu().numpy() history.append(loss) train_loss = np.mean(history) history = [] with torch.no_grad(): for idx,(img1,img2,target) in enumerate(val_dataloader): img1 = img1.to(device) img2 = img2.to(device) target = target.to(device) pred1 = model(img1) pred2 = model(img2) loss = contrastive_loss(pred1,pred2,target) loss = loss.detach().cpu().numpy() history.append(loss) val_loss = np.mean(history) print(f'train_loss:{train_loss},val_loss:{val_loss}')

这里为了加快训练,我把batch-size增加到了128个,其他的并没有改变:

这是运行的10个epoch的结果,不要忘记把模型保存一下:

torch.save(model.state_dict(),'saimese.pth')

差不多是这个样子,然后看一看验证集的可视化效果,这里使用的是t-sne高位特征可视化的方法,其内核是PCA降维:

from sklearn import manifold'''X是特征,不包含target;X_tsne是已经降维之后的特征'''tsne = manifold.TSNE(n_components=2, init='pca', random_state=501)X_tsne = tsne.fit_transform(X)print("Org data dimension is {}. Embedded data dimension is {}".format(X.shape[-1], X_tsne.shape[-1])) x_min, x_max = X_tsne.min(0), X_tsne.max(0)X_norm = (X_tsne - x_min) / (x_max - x_min) # 归一化plt.figure(figsize=(8, 8))for i in range(10): plt.scatter(X_norm[y==i][:,0],X_norm[y==i][:,1],alpha=0.3,label=f'{i}')plt.legend()

输入图像为:

可以看得出来,不同类别之间划分的是比较好的,可以看到不同类别之间的距离还是比较大的,比较明显的,甚至可以放下公众号的名字。这里使用的隐变量是8。

这里有一个问题,我内心已有答案不知大家的想法如何,假如我把z潜变量的维度直接改成2,这样就不需要使用tsne和pca的方法来降低维度就可以直接可视化,但是这样的话可视化的效果并不比从8降维到2来可视化的效果好,这是为什么呢?

提示:一方面在于维度过小导致信息的缺失,但是这个解释站不住脚,因为PCA其实等价于一个退化的线形层,所以PCA同样会造成这种缺失;我认为关键应该是损失函数中的欧式距离的计算,如果维度高,那么欧式距离就会偏大,这样需要相应的调整MARGIN的数值。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。