搭建神经网络实现简单图片分类

数据来源于吴恩达L2HW3(SIGNS 数据集),训练集包含1800张64*64像素的彩色图片,图片内容为手势,表示从0到5的数字,所要做的是搭建较深的神经网络,以实现图片分类。测试集包含120张图片。

数据集读取:

def load_dataset():
    %cd '/content/drive/MyDrive/Colab Notebooks/吴恩达L2HW3/dataset'
    train_dataset = h5py.File('train_signs.h5', "r")
    train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
    train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels

    test_dataset = h5py.File('test_signs.h5', "r")
    test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
    test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels

    classes = np.array(test_dataset["list_classes"][:]) # the list of classes
    
    train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
    test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
    
    return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
X_train_orig , Y_train_orig , X_test_orig , Y_test_orig , classes = load_dataset()
index = 12
plt.imshow(X_train_orig[index])
plt.show()
print(X_train_orig.shape)#1080张图片,64*64*3
Y_train_orig.shape

 

 数据预处理 :

train.sign.h5文件包含的是训练集,train_set_x为64*64*3*1800的tensor,1800为样本数,train_set_y为所对应的类别,维度为6*1080,需要首先每一样本数据进行归一化(/255),之后进行flatten才可输入模型,flatten之后的维度为(122280,1800)(X_train)

X_train_flatten=X_train_orig.reshape(X_train_orig.shape[0], -1).T
X_train_flatten.shape#每一列代表一个样本
X_test_flatten = X_test_orig.reshape(X_test_orig.shape[0], -1).T
#归一化
X_train_flatten=X_train_flatten/255
X_test_flatten=X_test_flatten/255

对训练集进行随机划分(Mini-Batch):

def random_mini_batches(X,Y,mini_batch_size,seed):
    m=X.shape[1]
    mini_batches=[]
    np.random.seed(seed)
    permutation=list(np.random.permutation(m))
    shuffled_X=X[:,permutation]
    shuffled_Y=Y[:,permutation]
    num_complete_minibatches=math.floor(m/mini_batch_size)
    for k in range(num_complete_minibatches):
      mini_batch_X=shuffled_X[:,k*mini_batch_size:(k+1)*mini_batch_size]
      mini_batch_Y=shuffled_Y[:,k*mini_batch_size:(k+1)*mini_batch_size]
      mini_batch=(mini_batch_X,mini_batch_Y)
      mini_batches.append(mini_batch)
    if m % mini_batch_size != 0:
      mini_batch_X = shuffled_X[:,num_complete_minibatches*mini_batch_size:m]
      mini_batch_Y = shuffled_Y[:,num_complete_minibatches*mini_batch_size:m]
      mini_batch = (mini_batch_X,mini_batch_Y)
      mini_batches.append(mini_batch)
    return mini_batches

shuffle:如下所示,创建训练集(X,Y)的随机打乱版本。X和Y中的每一列代表一个训练示例。随机打乱是在X和Y之间同步完成的。 

 

Partition:将打乱后的(X,Y)划分为大小为mini_batch_size(此处为32)的小批处理。训练示例的数量并不总是可以被mini_batch_size整除。最后的小批量可能较小。

模型搭建:全连接层-->relu-->全连接层-->relu-->全连接层

class Model(torch.nn.Module):
  def __init__(self,n_x,h1,h2,n_y):
    super(Model,self).__init__()
    self.linear1=torch.nn.Linear(n_x,h1)#(上一层特征数,该层神经元数)
    self.relu1=torch.nn.ReLU()
    self.linear2=torch.nn.Linear(h1,h2)
    self.relu2=torch.nn.ReLU()
    self.linear3=torch.nn.Linear(h2,n_y)
    self.model=torch.nn.Sequential(self.linear1,self.relu1,self.linear2,self.relu2,self.linear3)
  def forward(self,x):
    return self.model(x)

 训练数据输入模型:

m=Model(X_train_flatten.shape[0],25,12,6)#隐藏层神经元数为25,12,6最后一层输出对应类别的概率
num = torch.cuda.device_count()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
X_train_flatten = torch.from_numpy(X_train_flatten).to(torch.float32).to(device)
Y_train = torch.from_numpy(Y_train_orig).to(torch.float32).to(device)
X_test_flatten = torch.from_numpy(X_test_flatten).to(torch.float32).to(device)
Y_test = torch.from_numpy(Y_test_orig).to(torch.float32).to(device)

模型参数的设定:

m.to(device)
epoch_num = 2000
learning_rate = 0.0001
minibatch_size = 32
seed = 3
costs = []
optimizer = torch.optim.Adam(m.model.parameters(), lr=learning_rate)
loss_func = torch.nn.CrossEntropyLoss()

模型训练:

for epoch in range(epoch_num):
  num_minibatches = int(X_train_flatten.shape[1] / minibatch_size)
  minibatches = random_mini_batches(X_train_flatten, Y_train, minibatch_size, seed)
  epoch_cost = 0
  for minibatch in minibatches:
    (minibatch_X, minibatch_Y) = minibatch
    y_pred = m.forward(minibatch_X.T)
    y = minibatch_Y.T
    y = y.view(-1)
    loss = loss_func(y_pred, y.long())
    epoch_cost = epoch_cost + loss.item()#在pytorch里用item取出这个唯一的元素
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
  epoch_cost = epoch_cost / (num_minibatches + 1)
  if epoch % 5 == 0:
    costs.append(epoch_cost)
            # 是否打印:
    if epoch % 100 == 0:
      print("epoch = " + str(epoch) + "    epoch_cost = " + str(epoch_cost))

这里需要注意:计算损失时,我们需要将预测标签值y_pred和实际标签值y传入损失函数中,y_pred的维度为(n,6),而y的维度为(n),交叉熵函数(pytorch)会在内部将y转换为one-hot形式,y的维度会变成(n,6)。而在tensorflow框架中,损失函数不会帮我们完成one-hot的转换,我们要自己完成。 

epoch = 0    epoch_cost = 1.7447822058902067
epoch = 100    epoch_cost = 1.0144566087161793
epoch = 200    epoch_cost = 0.8499525382238275
epoch = 300    epoch_cost = 0.7405223215327543
epoch = 400    epoch_cost = 0.6508408206350663
epoch = 500    epoch_cost = 0.5719360849436592
epoch = 600    epoch_cost = 0.5000492202885011
epoch = 700    epoch_cost = 0.4312421894248794
epoch = 800    epoch_cost = 0.36556195949806886
epoch = 900    epoch_cost = 0.3063356779954013
epoch = 1000    epoch_cost = 0.25039714048890505
epoch = 1100    epoch_cost = 0.19280040614745197
epoch = 1200    epoch_cost = 0.14023028938647578
epoch = 1300    epoch_cost = 0.10207015522481765
epoch = 1400    epoch_cost = 0.11564182287410778
epoch = 1500    epoch_cost = 0.09902713168412447
epoch = 1600    epoch_cost = 0.06645032955224023
epoch = 1700    epoch_cost = 0.045455615638810044
epoch = 1800    epoch_cost = 0.07567436467198764
epoch = 1900    epoch_cost = 0.02966493705068441
#模型保存:
torch.save(m,'/content/drive/MyDrive/Colab Notebooks/吴恩达L2HW3/图片数字分辨.pth')

 测试集上的表现:

y_test_pred=m.forward(X_test_flatten.T)
y = Y_test.T
y = y.view(-1)
loss = loss_func(y_test_pred, y.long())
y_model_pred=[]
for i in range(X_test_flatten.shape[1]):
  y_model_pred.append(torch.argmax(y_test_pred[i],dim=0).item())
for index in range(X_test_flatten.shape[1]):
  plt.imshow(X_test_orig[index])
  plt.show()
  print(y_model_pred[index])

 

0

0

0

0

2

 

 

 

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于paddle搭建神经网络实现多种水果图像分类识别python源码+项目说明+数据集.zip ### 数据集介绍 - 来源:爬虫爬取百度图片 - 内容:总共1036水果图片,共5个类别(苹果288张、香蕉275张、葡萄216张、橙子276张、梨251张) - 图像预处理时,将其中的10%作为测试数据,90%作为训练数据 ### 总体步骤 - 数据预处理:建立分类文件,建立数据集和测试集 - 训练与模型评估 - 读取测试图片进行预测 #### 步骤一:预处理 - 图片位于5个目录中,遍历每个目录,将其中的90%写入训练集文件中,10%写入测试集文件中,文件中记录了图片的路径,用于数据读取器进行读取 - 生成3个文件:readme.json(汇总文件)、train_list(训练集)、test.list(测试集) - 注意 - 数据集的路径是否正确 - 生成的汇总文件、训练集文件、测试集文件是否正确 #### 步骤二:模型训练与评估 - 模型: - 输入层 ——》 卷积-池化层-dropout ——》 卷积-池化层-dropout ——》 卷积-池化层-dropout ——》全连接层 ——》dropout ——》 全连接层 ——》输出 #### 步骤三:预测 ### 优化手段 - 样本 - 增大样本数量 - 数据增强 - 形态变化:翻转、平移,随机修剪,尺度变化,旋转(卷积核的旋转) - 色彩变化:图像白化(将图像本身归一化成Gaussian(0,1)分布) - 加入噪声 - 模型和参数 - 丢弃学习:按照一定的比率丢弃神经元输出 - 权重的衰减:为损失函数添加惩罚项使得训练模型参数尽可能的小 - 批量正则化:在每一层输入之前增加归一化处理,使得均值为0,标准差为1,将数据限制在统一分布之下 - 变化学习率 - 更换精度更高的网络模型,如由简单的CNN换成VGG、GooLeNet .....
好的,我可以为你讲解如何使用numpy搭建神经网络并完成图像分类任务。 首先,我们需要导入numpy库和一个图像数据集。假设我们使用的是MNIST数据集,它包含60,000张28x28像素的手写数字图片和10,000张测试图片,每张图片都有一个对应的数字标签。 接下来,我们需要定义一个多层感知器(MLP)模型。MLP是最简单神经网络之一,它由多个全连接层组成。我们可以使用numpy中的dot函数来实现矩阵乘法,从而计算每一层的输出。在每个隐藏层之后,我们可以添加一个激活函数(如ReLU)来增加模型的非线性能力,并使其能够更好地拟合数据。 下面是一个简单的三层MLP模型的代码: ```python import numpy as np class MLP: def __init__(self, input_size, hidden_size, output_size): self.W1 = np.random.randn(input_size, hidden_size) self.b1 = np.zeros(hidden_size) self.W2 = np.random.randn(hidden_size, output_size) self.b2 = np.zeros(output_size) def forward(self, X): self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = np.maximum(0, self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 exp_scores = np.exp(self.z2) return exp_scores / np.sum(exp_scores, axis=1, keepdims=True) ``` 在上面的代码中,我们使用了Xavier初始化方法来初始化权重,并使用了softmax函数作为输出层的激活函数。在训练过程中,我们可以使用反向传播算法来计算每个权重的梯度,并使用梯度下降算法来更新它们。 最后,我们可以使用训练好的模型来预测测试数据集中的图片。我们可以将每个测试图片输入到模型中,并选择输出向量中最大的值作为预测的数字标签。 ```python model = MLP(784, 256, 10) # 训练模型 # 预测测试数据集 test_scores = model.forward(X_test) test_predictions = np.argmax(test_scores, axis=1) ``` 这就是使用numpy搭建神经网络并完成图像分类任务的基本过程。当然,在实际应用中,我们可能需要添加更多的层和技巧来提高模型的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值