作业过程记录:连体网络MINIST识别

连体网络MINIST识别 作业过程记录

1.minist 数据

tensorsflow中文社区提供python源码自动下载和安装,加到自己代码文件里:

import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

训练集:60000行的训练数据集(mnist.train)
测试数据:10000行的测试数据集(mnist.test)
每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。
图片:“xs”
标签:“ys”
训练数据集和测试数据集都包含xs和ys,
比如训练数据集的图片是 mnist.train.images ,
训练数据集的标签是 mnist.train.labels。
每张图片28*28=784(可展成向量)
在MNIST训练数据集中,mnist.train.images 是一个形状为 [60000, 784]
mnist.train.labels 是一个 [60000, 10] 的数字矩阵。

1. tesnsorflow minist入门

1.1 Softmax回归介绍

softmax模型可以用来给不同的对象分配概率。即使在之后,我们训练更加精细的模型时,最后一步也需要用softmax来分配概率。比如说,我们的模型可能推测一张包含9的图片代表数字9的概率是80%但是判断它是8的概率是5%(因为8和9都有上半部分的小圆),然后给予它代表其他数字的概率更小的值。

softmax回归(softmax regression)分两步:
第一步:为了得到一张给定图片属于某个特定数字类的证据(evidence),我们对图片像素值进行加权求和。
这里写图片描述
我们也需要加入一个额外的偏置量(bias),因为输入往往会带有一些无关的干扰量。因此对于给定的输入图片 x 它代表的是数字 i 的证据可以表示为:

evidencei=jWi,jxj+bi e v i d e n c e i = ∑ j W i , j x j + b i

其中 Wi W i 代表权重, bi b i 代表数字 i 类的偏置量,j 代表给定图片 x 的像素索引用于像素求和。
第二步
然后用softmax函数可以把这些证据转换成概率 y:
y=softmax(evidence) y = s o f t m a x ( e v i d e n c e )

这里的softmax可以看成是一个激励(activation)函数或者链接(link)函数,把我们定义的线性函数的输出转换成我们想要的格式,也就是关于10个数字类的概率分布。因此,给定一张图片,它对于每一个数字的吻合度可以被softmax函数转换成为一个概率值。softmax函数可以定义为:
softmax(x)=normalize(exp(x)) s o f t m a x ( x ) = n o r m a l i z e ( e x p ( x ) )

展开等式右边的子式,可以得到:
softmax(x)i=exp(xi)jexp(xj) s o f t m a x ( x ) i = e x p ( x i ) ∑ j e x p ( x j )

softmax可以理解为下:
这里写图片描述

1.2 softmax回归模型实现

import tensorflow as tf
x = tf.placeholder("float", [None, 784]) #None表示此张量的第一个维度可以是任何长度的
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x,W) + b)

1.3 训练模型

loss损失函数
之一:“交叉熵”(cross-entropy),定义如下

Hy(y)=iyilog(yi) H y ′ ( y ) = − ∑ i y i ′ l o g ( y i )

y 是我们预测的概率分布, y’ 是实际的分布(我们输入的one-hot vector)。

y_ = tf.placeholder("float", [None,10]) #新的占位符用于输入正确值:
cross_entropy = -tf.reduce_sum(y_*tf.log(y)) 
#tf.log 计算 y 的每个元素的对数, y_ 的每一个元素和 tf.log(y_) 的对应元素相乘,用 tf.reduce_sum 计算张量的所有元素的总和
#注意,这里的交叉熵不仅仅用来衡量单一的一对预测和真实值,而是所有100幅图片的交叉熵的总和。
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

2.作业要求

连体网络MINIST识别:
构建如下图所示识别模型:该模型由两个相同的网络G(x)组成。两个网络共享相同的参数W.
Alt text
该模型实现如下的功能,输入两个MINIST图片,判断是不是同一个数字。

例如,输入 负样本对:X1=6的图片 , X2=9的图片 输出:1
输入 正样本对:X1=3的图片 , X2=3的图片 输出:0

G(x)是一个一般的全连接网络(两边的网络结构是一样的!共享参数W、b等),由结构可以自己设计。比如建议两层网络:hidden1:784(28x28)->500; hidden2: 500->10,使用relu。也可以尝试其他节点数组合,和其他非线性变换函数。

强调:G(X)的功能定义为提取一张minist图像的特征。

该模型的训练采用如下损失函数:
这里写图片描述
注意:使用此loss需要定 y=0 (两个数字相同)y=1 (两个数字不同)!!!!!!!!!!

要求:合理设计网络,及训练数据采样方法,提升网络的正负样本对的预测精度:用ACC衡量。
提交训练、测试代码。及训练、测试截图。

提示:
1. minist读取可以用tensorflow里写好的工具

from tensorflow.examples.tutorials.mnist import input_data
...
mnist = input_data.read_data_sets('./data/mnist',one_hot=False)
print(mnist.validation.num_examples)
print(mnist.train.num_examples)
print(mnist.test.num_examples)
...
  1. 正负样本对的合理采样设计会影响训练效果:
    例如如下的方式:
for itera in range(iter):
        x_1, y_1 = mnist.train.next_batch(batch_size)
        x_2, y_2 = mnist.train.next_batch(batch_size)
        y_s = np.array(y_1!=y_2,dtype=np.float32)

这样只能碰运气碰到几对正样本,但大多数都可能是负样本。两个类型的样本数不平衡。
3. 损失函数中构建需要都用tf函数,否则无法构建计算图:
常数需要用tf.constant
其他函数例如:E_w = tf.sqrt(tf.reduce_sum(tf.square(o1-o2),1)), tf.exp()等请自查
4. 两个网络结构是一样的!共享参数。怎样共享参数?考虑我们之前的参数复用练习。
5. 建议用AdamOptimizer优化器,其他参数建议
lr = 0.01
iter = 20000
batch_size = 64

3.github代码解析

3.1 Python类中的init() 和 self 的解析

此处的self,是个对象(Object),是当前类的实例。应的self.valueName 和 self.function()中的valueName:表示self对象,即实例的变量。与其他的,Class的变量,全局的变量,局部的变量,是相对应的。function:表示是调用的是self对象,即实例的函数。与其他的全局的函数,是相对应的。

3.2 tf.bias_add(vaue,bias,name=None)和tf.add(x,y,name=None)

tf.bias_add(vaue,bias,name=None)

输入:
value: Tensor
bias:一维的tensor,数据维度和value的最后一维相同。数据类型和value相同
输出:tensor

import tensorflow as tf

a=tf.constant([[1,1],[2,2],[3,3]],dtype=tf.float32)
b=tf.constant([1,-1],dtype=tf.float32)
c=tf.constant([1],dtype=tf.float32)

with tf.Session() as sess:
    print('bias_add:')
    print(sess.run(tf.nn.bias_add(a, b)))
    #执行下面语句错误
    #print(sess.run(tf.nn.bias_add(a, c)))

    print('add:')
    print(sess.run(tf.add(a, c)))
#输出:
#bias_add:
#[[ 2. 0.]
#[ 3. 1.]
#[ 4. 2.]]
#add:
#[[ 2. 2.]
#[ 3. 3.]
#[ 4. 4.]]
tf.add(x,y,name=None)

tf.nn.bias_add()是 tf.add 的一个特例,也即 tf.add 支持的操作比 tf.nn.bias_add 更多。二者均支持 broadcasting(广播机制),也即两个操作数最后一个维度保持一致。除了支持最后一个维度保持一致的两个操作数相加外,tf.add 还支持第二个操作数是一维的情况,例。

    Weights = tf.get_variable(name = 'Weights', initializer = tf.zeros([2,1]))  #reuse
    biases = tf.get_variable(name = 'biases',initializer = tf.zeros([1,1]))   #reuse
    y = tf.add()tf.matmul(traininput,Weights),biase)
    #traininput(30,2)
    #得到的y(30,1)

3.3 tf.Session() 和tf.InteractiveSession()

sess = tf.InteractiveSession()
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
# We can just use 'c.eval()' without passing 'sess'
print(c.eval())
sess.close()
#输出 30

老师上课说的是 没有Session()启动,就不能tensorflow。
tf.InteractiveSession ()需要的代码少,原因就是它允许变量不需要使用session就可以产生结构。它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。
tf.Session():需要在启动session之前构建整个计算图,然后启动该计算图。
使用tf.InteractiveSession()来构建会话的时候,我们可以先构建一个session然后再定义操作(operation),如果我们使用tf.Session()来构建会话我们需要在会话构建之前定义好全部的操作(operation)然后再构建会话。

3.4 tf.reduce_sum():

作用:我的理解是计算tensor某个维度的和,可以给数据降维啊
参数:
input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None
看例子:

  x = tf.constant([[1, 1, 1], [1, 1, 1]]) #2*3维数据
  tf.reduce_sum(x)  # 6,在所有维度加起来
  tf.reduce_sum(x, 0)  # [2, 2, 2],在列方向
  tf.reduce_sum(x, 1)  # [3, 3],在行方向
  tf.reduce_sum(x, 1, keep_dims=True)  # [[3], [3]],keep_dims=True 减少的维度限制在1的长度
  tf.reduce_sum(x, [0, 1])  # 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
很高兴听到您想要实现一个手写神经网络识别minist手写数字。以下是一个基本的Python代码实现: 首先,我们需要导入必要的库: ```python import numpy as np import matplotlib.pyplot as plt import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data ``` 然后,我们需要加载minist数据集: ```python mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) ``` 接着,我们需要定义我们的神经网络模型。我们将使用一个三层的全连接网络,其中第一层有784个输入神经元(对应于MNIST图像的像素数量),第二层有256个隐藏神经元,第三层有10个输出神经元(对应于10个数字分类)。 ```python # 定义网络参数 n_input = 784 n_hidden_1 = 256 n_classes = 10 # 定义占位符 x = tf.placeholder("float", [None, n_input]) y = tf.placeholder("float", [None, n_classes]) # 定义权重和偏置 weights = { 'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'out': tf.Variable(tf.random_normal([n_hidden_1, n_classes])) } biases = { 'b1': tf.Variable(tf.random_normal([n_hidden_1])), 'out': tf.Variable(tf.random_normal([n_classes])) } # 定义网络结构 def multilayer_perceptron(x, weights, biases): # 第一层隐藏层 layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1']) layer_1 = tf.nn.relu(layer_1) # 输出层 out_layer = tf.matmul(layer_1, weights['out']) + biases['out'] return out_layer # 定义模型 pred = multilayer_perceptron(x, weights, biases) ``` 然后,我们需要定义我们的损失函数和优化器。我们将使用交叉熵损失函数和Adam优化器。 ```python # 定义损失函数和优化器 cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(cost) ``` 接下来,我们定义训练模型的参数。我们将使用100个批次,每个批次大小为128。 ```python # 定义训练参数 training_epochs = 100 batch_size = 128 display_step = 1 ``` 现在,我们可以开始训练我们的模型。我们将迭代训练数据集100次,并在每次迭代后计算损失和准确率。 ```python # 启动会话 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 训练循环 for epoch in range(training_epochs): avg_cost = 0. total_batch = int(mnist

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值