自己做的网站访问速度慢,做pcr查基因序列的网站,wordpress 账号 登陆不了,点餐小程序开发需要多少钱识别手写图片
因为这个例子是 TensorFlow 官方的例子#xff0c;不会说的太详细#xff0c;会加入了一点个人的理解#xff0c;因为TensorFlow提供了各种工具和库#xff0c;帮助开发人员构建和训练基于神经网络的模型。TensorFlow 中最重要的概念是张量#xff08;Tenso…识别手写图片
因为这个例子是 TensorFlow 官方的例子不会说的太详细会加入了一点个人的理解因为TensorFlow提供了各种工具和库帮助开发人员构建和训练基于神经网络的模型。TensorFlow 中最重要的概念是张量Tensor它代表了多维数组或矩阵因此 TensorFlow 支持各种不同类型的计算如线性回归、逻辑回归、卷积神经网络、循环神经网络等。所以帮我们极大减少了对数学与算法基础的要求。
准备数据
这里用来识别的手写图片大致是这样的为了降低复杂度每个图片是 28*28 大小。 但是直接丢图片给我们的模型模型是不认识的所以必须要对图片进行一些处理。
如果了解线性代数大概知道图片的每个像素点其实可以表示为一个二维的矩阵对图片做各种变换比如翻转啊什么的就是对这个矩阵进行运算于是我们的手写图片大概可以看成是这样的 这个矩阵展开成一个向量长度是 28*28784。我们还需要另一个东西用来告诉模型我们认为这个图片是几也就是给图片打个 label。这个 label 也不是随便打的这里用一个类似有 10 个元素的数组其中只有一个是 1其它都是 0哪位为 1 表示对应的图片是几例如表示数字 8 的标签值就是 ([0,0,0,0,0,0,0,0,1,0])。
这些就是单张图片的数据处理实际上为了高效的训练模型会把图片数据和 label 数据分别打包到一起也就是 MNIST 数据集了。
MNIST数据集
MNIST 数据集是一个入门级的计算机视觉数据集官网是Yann LeCuns website。 我们不需要手动去下载这个数据集 1.0 的 TensorFlow 会自动下载。
这个训练数据集有 55000 个图片数据用张量的方式组织的形状如 [55000,784]如下图 还记得为啥是 784 吗因为 28*28 的图片。 label 也是如此[55000,10] 这个数据集里面除了有训练用的数据之外还有 10000 个测试模型准确度的数据。
整个数据集大概是这样的 现在数据有了来看下我们的模型。
Softmax 回归模型
Softmax 中文名叫归一化指数函数这个模型可以用来给不同的对象分配概率。比如判断 的时候可能认为有 80% 是 9有 5% 认为可能是 8因为上面都有个圈。
我们对图片像素值进行加权求和。比如某个像素具有很强的证据说明这个图不是 1则这个像素相应的权值为负数相反如果这个像素特别有利则权值为正数。
如下图红色区域代表负数权值蓝色代表正数权值。 同时还有一个偏置量(bias) 用来减小一些无关的干扰量。
Softmax 回归模型的原理大概就是这样更多的推导过程可以查阅一下官方文档有比较详细的内容。
说了那么久终于可以上代码了。
训练模型
具体引入的一些包这里就不一一列出来主要是两个一个是 tensorflow 本身另一个是官方例子里面用来输入数据用的方法。
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
之后就可以建立我们的模型。
# Create the modelx tf.placeholder(tf.float32, [None, 784])W tf.Variable(tf.zeros([784, 10]))b tf.Variable(tf.zeros([10]))y tf.matmul(x, W) b 这里的代码都是类似占位符要填了数据才有用。
x 是从图片数据文件里面读来的理解为一个常量一个输入值因为是 28*28 的图片所以这里是 784W 代表权重因为有 784 个点然后有 10 个数字的权重所以是 [784, 10]模型运算过程中会不断调整这个值可以理解为一个变量b 代表偏置量每个数字的偏置量都不同所以这里是 10模型运算过程中也会不断调整这个值也是一个变量y 基于前面的数据矩阵乘积计算。
tf.zeros 表示初始化为 0。
我们会需要一个东西来接受正确的输入也就是放训练时准确的 label。 # Define loss and optimizery_ tf.placeholder(tf.float32, [None, 10])
我们会用一个叫交叉熵的东西来衡量我们的预测的「惊讶」程度。
关于交叉熵举个例子我们平常写代码的时候一按编译一切顺利程序跑起来了我们就没那么「惊讶」因为我们的代码是那么的优秀而如果一按编译整个就 Crash 了我们很「惊讶」一脸蒙逼的想这怎么可能。
交叉熵感性的认识就是表达这个的当输出的值和我们的期望是一致的时候我们就「惊讶」值就比较低当输出值不是我们期望的时候「惊讶」值就比较高。 cross_entropy tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labelsy_, logitsy))
这里就用了 TensorFlow 实现的 softmax 模型来计算交叉熵。 交叉熵就是我们想要尽量优化的值让结果符合预期不要让我们太「惊讶」。
TensorFlow 会自动使用反向传播算法(backpropagation algorithm) 来有效的确定变量是如何影响你想最小化的交叉熵。然后 TensorFlow 会用你选择的优化算法来不断地修改变量以降低交叉熵。
train_step tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
这里用了梯度下降算法gradient descent algorithm来优化交叉熵这里是以 0.5 的速度来一点点的优化交叉熵。
之后就是初始化变量以及启动 Session
sess tf.InteractiveSession() tf.global_variables_initializer().run()
启动之后开始训练 # Train for _ in range(1000): batch_xs, batch_ys mnist.train.next_batch(100) sess.run(train_step, feed_dict{x: batch_xs, y_: batch_ys})
这里训练 1000 次每次随机找 100 个数据来练习这里的 feed_dict{x: batch_xs, y_: batch_ys}就是我们前面那设置的两个留着占位的输入值。
到这里基本训练就完成了。
评估模型
训练完之后我们来评估一下模型的准确度。 # Test trained modelcorrect_prediction tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))accuracy tf.reduce_mean(tf.cast(correct_prediction, tf.float32))print(sess.run(accuracy, feed_dict{x: mnist.test.images,y_: mnist.test.labels}))tf.argmax 给出某个tensor对象在某一维上的其数据最大值所在的索引值。因为我们的 label 只有一个 1所以 tf.argmax(_y, 1) 就是 label 的索引也就是表示图片是几。把计算值和预测值 equal 一下就可以得出模型算的是否准确。 下面的 accuracy 计算的是一个整体的精确度。
这里填入的数据不是训练数据是测试数据和测试 label。
最终结果我的是 0.915191.51% 的准确度。官方说这个不太好如果用一些更好的模型比如多层卷积网络等这个识别率可以到 99% 以上。
官方的例子到这里就结束了虽然说识别了几万张图片但是我一张像样的图片都没看到于是我决定想办法拿这个模型真正找几个图片测试一下。
用模型测试
看下上面的例子重点就是放测试数据进去这里如果我们要拿图片测需要先把图片变成相应格式的数据。
sess.run(accuracy, feed_dict{x: mnist.test.images, y_: mnist.test.labels})
看下这里 mnist 是从 tensorflow.examples.tutorials.mnist 中的 input_data 的 read_data_sets 方法中来的。
from tensorflow.examples.tutorials.mnist import input_data
mnist input_data.read_data_sets(FLAGS.data_dir, one_hotTrue)
Python 就是好有啥不懂看下源码。源码的在线地址在这里
打开找 read_data_sets 方法发现
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
在这个文件里面。
def read_data_sets(train_dir,fake_dataFalse,one_hotFalse,dtypedtypes.float32,reshapeTrue,validation_size5000):.........train DataSet(train_images, train_labels, dtypedtype, reshapereshape)validation DataSet(validation_images,validation_labels,dtypedtype,reshapereshape)test DataSet(test_images, test_labels, dtypedtype, reshapereshape)return base.Datasets(traintrain, validationvalidation, testtest)
可以看到最后返回的都是是一个对象而我们用的 feeddict{x: mnist.test.images, y: mnist.test.labels} 就是从这来的是一个 DataSet 对象。这个对象也在这个文件里面。
class DataSet(object):def __init__(self,images,labels,fake_dataFalse,one_hotFalse,dtypedtypes.float32,reshapeTrue):Construct a DataSet.one_hot arg is used only if fake_data is true. dtype can be eitheruint8 to leave the input as [0, 255], or float32 to rescale into[0, 1].......
这个对象很长我就只挑重点了主要看构造方法。一定要传入的有 images 和 labels。其实这里已经比较明朗了我们只要把单张图片弄成 mnist 格式分别传入到这个 DataSet 里面就可以得到我们要的数据。
网上查了下还真有代码地址对应的文章www.jianshu.com/p/419557758…文章讲的有点不清楚需要针对 TensorFlow 1.0 版本以及实际目录情况做点修改。
直接上我修改后的代码
from PIL import Image
from numpy import *def GetImage(filelist):width28height28valuezeros([1,width,height,1])value[0,0,0,0]-1labelzeros([1,10])label[0,0]-1for filename in filelist:imgarray(Image.open(filename).convert(L))width,heightshape(img);index0tmp_valuezeros([1,width,height,1])for i in range(width):for j in range(height):tmp_value[0,i,j,0]img[i,j]index1if(value[0,0,0,0]-1):valuetmp_valueelse:valueconcatenate((value,tmp_value))tmp_labelzeros([1,10])indexint(filename.strip().split(/)[2][0])print input:,indextmp_label[0,index]1if(label[0,0]-1):labeltmp_labelelse:labelconcatenate((label,tmp_label))return array(value),array(label)
这里读取图片依赖 PIL 这个库由于 PIL 比较少维护了可以用它的一个分支 Pillow 来代替。另外依赖 numpy 这个科学计算库没装的要装一下。
这里就是把图片读取并按 mnist 格式化label 是取图片文件名的第一个字所以图片要用数字开头命名。
如果懒得 PS 画或者手写的画可以把测试数据集的数据给转回图片实测成功参考这篇文章如何用python解析mnist图片
新建一个文件夹叫 test_num里面图片如下这里命名就是 label 值可以看到 label 和图片是对应的 开始测试 print(Start Test Images)dir_name ./test_numfiles glob2.glob(dir_name /*.png)cnt len(files)for i in range(cnt):print(files[i])test_img, test_label GetImage([files[i]])testDataSet DataSet(test_img, test_label, dtypetf.float32)res accuracy.eval({x: testDataSet.images, y_: testDataSet.labels})print(output: , res)print(----------
这里用了 glob2 这个库来遍历以及过滤文件需要安装常规的遍历会把 Mac 上的 .DS_Store 文件也会遍历进去。 可以看到我们打的 label 和模型算出来的是相符的。
然后我们可以打乱文件名把 9 说成 8把 0 也说成 8 可以看到我们的 label 和模型算出来的是不相符的。 恭喜到着你就完成了一次简单的人工智能之旅。
总结
从这个例子中我们可以大致知道 TensorFlow 的运行模式 例子中是每次都要走一遍训练流程实际上是可以用 tf.train.Saver() 来保存训练好的模型的。这个入门例子完成之后能对 TensorFlow 有个感性认识。
TensorFlow 没有那么神秘没有我们想的那么复杂也没有我们想的那么简单并且还有很多数学知识要补充呢。