机器学习入门之HelloWorld(Tensorflow)-深蓝源码网


时间: 2020-09-03 00:08:26 人气: 2280 评论: 0

作者:陈贻东|腾讯移动客户端开发工程师

源码下载地址:https://share.weiyun.com/a0c1664d334c4c67ed51fc5e0ac5f2b2

初学机器学习,写篇文章mark一下,希望能为将入坑者解点惑。本文介绍一些机器学习的入门知识,从安装环境到跑通机器学习入门程序MNIST demo。

内容提纲:

  1. 环境搭建
  2. 了解Tensorflow运行机制
  3. MNIST(手写数字识别 ) softmax性线回归
  4. MNIST 深度卷积神经网络(CNN)
  5. tools 工具类
  6. CPU & GPU & multi GPU
  7. 学习资料

1 环境搭建 (Windows)

  • 安装虚拟环境 Anaconda,方便python包管理和环境隔离。

Anaconda3 4.2 https://www.anaconda.com/downloads,自带python 3.5。

  • 创建tensorflow隔离环境。打开Anaconda安装后的终端Anaconda Prompt,执行下面命令
conda create -n tensorflow python=3.5 #创建名为tensorflow,python版本为3.5的虚拟环境
activate tensorflow #激活这个环境  
deactivate #退出当前虚拟环境。这个不用执行

CPU 版本

pip install tensorflow #通过包管理来安装
pip install whl-file #通过下载 whl 文件安装,tensorflow-cpu安装包:http://mirrors.oa.com/tensorflow/windows/cpu/tensorflow-1.2.1-cp35-cp35m-win_amd64.whl, cp35是指python3.5

GPU 版本。我的笔记本是技持NVIDIA显卡的,可以安装cuda,GPU比CPU快很多,不过笔记本的显存不大,小模型还可以跑,大模型建议在本地用CPU跑通,到Tesla平台上训练。

注意点:选择正确的 CUDA 和 cuDNN 版本搭配,不要只安装最新版本,tensorflow可能不支持。

目前Tensorflow已支持到CUDA 9 & cuDNN 7,之前本人安装只支持CUDA 8 & cuDNN 6,所以用是的:

CUDA8.1 https://developer.nvidia.com/cuda-80-ga2-download-archive

cudnn 6 https://developer.nvidia.com/cudnn ,将cudnn包解压,把文件放到cuda安装的对应目录中,C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0,bin对应bin,include对应include,再添加bin目录到环境变量path中。

pip install tensorflow-gpu #通过包管理来安装
pip install whl-file #http://mirrors.oa.com/tensorflow/windows/gpu/tensorflow_gpu-1.2.1-cp35-cp35m-win_amd64.whl 
  • 一些python工具包安装。用到啥安啥就行, pip install,不行就找源码编译安装
(tensorflow) D:\> pip install opencv-python   #opencv, tensoflow 虚拟环境中
(tensorflow) D:\> pip install scipy    #图片读取写入,scipy.misc.imread
(tensorflow) D:\> pip install Pillow   #PIL/Pillow,这里有个坑,压缩过的PNG图,在1.x版本解析会出现透明通道质量下降,升级

2 了解Tensorflow运行机制

  • 上代码。注意注释说明
import tensorflow as tf
hello_world = tf.constant('Hello World!', dtype=tf.string) #常量tensor
print(hello_world) #这时hello_world是一个tensor,代表一个运算的输出
#out: Tensor("Const:0", shape=(), dtype=string)
hello = tf.placeholder(dtype=tf.string, shape=[None])#占位符tensor,在sess.run时赋值
world = tf.placeholder(dtype=tf.string, shape=[None])
hello_world2 = hello+world #加法运算tensor
print(hello_world2)
#out: Tensor("add:0", shape=(?,), dtype=string)
#math
x = tf.Variable([1.0, 2.0]) #变量tensor,可变。
y = tf.constant([3.0, 3.0])
mul = tf.multiply(x, y) #点乘运算tensor
#logical
rgb = tf.constant([[[255], [0], [126]]], dtype=tf.float32)
logical = tf.logical_or(tf.greater(rgb,250.), tf.less(rgb, 5.))#逻辑运算,rgb中>250 or <5的位置被标为True,其它False
where = tf.where(logical, tf.fill(tf.shape(rgb),1.), tf.fill(tf.shape(rgb),5.))#True的位置赋值1,False位置赋值5
# 启动默认图.
# sess = tf.Session()
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())#变量初始化
    result = sess.run(hello_world) #Fetch, 获取tensor运算结果
    print(result, result.decode(), hello_world.eval())#`t.eval()` is a shortcut for calling  `tf.get_default_session().run(t)`.
    #out: b'Hello World!' Hello World! b'Hello World!' #前辍'b'表示bytestring格式,decode解成string格式
    print(sess.run(hello, feed_dict={hello: ['Hello']}))
    #out: ['Hello']
    print(sess.run(hello_world2, feed_dict={hello: ['Hello'], world: [' World!']}))#Feed,占位符赋值
    #out: [b'Hello World!']
    print(sess.run(mul))
    #out: [ 3.  6.]
    print(sess.run(logical))
    #out: [[[ True] [ True] [False]]] #rgb中>250 or <5的位置被标为True,其它False
    print(sess.run(where))
    #out: [[[ 1.] [ 1.] [ 5.]]] #True的位置赋值1,False位置赋值5
#sess.close()#sess如果不是用with方式定义,需要close
  • Tensor。是一个句柄,代表一个运算的输出,但并没有存储运算输出的结果,需要通过tf.Session.run(Tensor)或者Tensor.eval()执行运算过程后,才能得到输出结果。A Tensor is a symbolic handle to one of the outputs of an Operation,It does not hold the values of that operation's output, but instead provides a means of computing those values in a TensorFlow.
  • Tensorflow运行过程:定义计算逻辑,构建图(Graph) => 通过会话(Session),获取结果数据。基本用法参见链接。

3 MNIST(手写数字识别 ) softmax性线回归

  • 分析

MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片:

它也包含每一张图片对应的标签,告诉我们这个是数字几。比如,上面这四张图片的标签分别是5,0,4,1。

数据集图片大小28x28,单通道灰度图。存储样式如下:

MNIST手写数字识别的目的是输入这样的包含手写数字的28x28的图片,预测出图片中包含的数字。

softmax线性回归认为图片中数字是N可能性由图像中每个像素点用

表示是 数字 i 的可能性,计算出所有数字(0-9)的可能性,也就是所有数字置信度,然后把可能性最高的数字作为预测值。

evidence的计算方式如下:

其中

代表权重,

代表数字 i 类的偏置量,j 代表给定图片 x 的像素索引(0~28x28=784),用于像素求和。即图片每个像素值x权重之和,再加上一个偏置b,得到可能性值。

引入softmax的目的是对可能性值做归一化normalize,让所有可能性之和为1。这样可以把这些可能性转换成概率 y

  • 开始实现

数据

X样本 size 28x28 = 784

Y样本 ,样式如

读取

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True) #total 55000,one_hot方式,图片x格式为1维数组,大小784
batch_xs, batch_ys = mnist.train.next_batch(batch_size) #分batch读取

 构建图(Graph)

Inference推理,由输入 x 到输出预测值 y 的推理过程

x = tf.placeholder(tf.float32, [None, 784], name="input")#None表示batch size待定
with tf.variable_scope("inference"):#定义作用域,名子inference
    W = tf.Variable(tf.zeros([784, 10])) #初值为0,size 784x10
    b = tf.Variable(tf.zeros([10])) #初值为0 size 10
    y = tf.matmul(x, W) + b #矩阵相乘

 Loss 损失函数,分类一般采用交叉熵,这里用的是softmax交交叉熵。交叉熵是用来度量两个概率分布间的差异性信息,交叉熵公式如下:

with tf.variable_scope("loss"):
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y), name="loss")
    #softmax交叉熵公式: z * -log(softmax(x)) + (1 - z) * -log(1 - softmax (x)) # x: logits, z: label

 计算loss的方法有很多种,常见的还有L1 loss 、L2 loss、sigmoid 交叉熵、联合loss、自定义loss...

Accuracy 准确率,预测值与真实值相同的概率。矩阵相乘输出y值是一个数组,tf.argmax函数可能从数据中找出最大元素下标,预测值的最大值下标和真值的最大值下标一致即为正确。

with tf.variable_scope("accuracy"):
    accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)), tf.float32), name="accuracy")

Training 训练,训练的目的是让Loss接近最小化,预测值接近真值,Tensorflow通过优化器Optimizers来实现。在y = Wx+b中,W、b在训练之初会赋初值(随机 or 0),经过Optimizer不短优化,Loss逼近最小值,使W、b不断接近理想值。W、b一起共784x10+10个参数。

train_step = tf.train.GradientDescentOptimizer(FLAGS.learning_rate).minimize(loss)

minimize函数:更新参数,让Loss最小化,包含两个步骤:计算梯度;更新参数。

grad_var = compute_gradients(loss
						 技术沙龙 教程文章 热点综合					

评论