前言
犹记得一周前, 对图形验证码有点想法, 自信满满的去做破解的工作, 但是实际被各种打脸, 不接触这行, 真不懂里面的套路;
关于图形验证码这块, 不管后面行还是不行, 都会写一篇出来, 当做经验总结也好, 但总不能停留在这里, 因为后面还有滑动验证码, 点触验证码等着去学习;
开篇
当今在互联网混, 不随口说出深度学习, 人工智能, 机器学习, 神经网络等词, 人家都怀疑是个假的互联网人了, 但不知道是否有同学跟 JB 一样, 傻傻分不清?
犹记得, 自从阿法狗那波, 业界似乎对机器学习推到一个新的高度??
本来是不太想沾这趟水的, 毕竟知道自己不是那个料, 但是最近被验证码折腾的够累的, 而图形验证码的确是深度学习的一个点, 于是乎还是想写下, 了解下, 至少对概念有点印象, 也不枉此行了;
小白用户, 如果对这块有不对的地方, 请各位同学及时提出哈, 谢谢啦~
扫盲
深度学习, 人工智能, 机器学习, 神经网络, 这 4 个词出现的比较多, 但是它们之间有什么关系呢? 尤其, 机器学习跟深度学习区别在哪里??
人工智能, 英文 Artificial Intelligence, 简称 AI, 那人工智能的目的是什么?
网上一大堆, 好听的叫解放 / 发展生产力, 解放人类, 总的来说是提高效率
但更好理解就是: 偷懒!
比如当你说一句话时, 机器能够识别成文字, 并理解你话的意思, 进行分析和对话等.
人工智能的核心在于智能两字, 那智能怎么来的? 主要归功于一种实现人工智能的方法 -- 机器学习;
那目前人工智能的应用场景有哪些:
OCR, 语音技术(比如 Siri), 大数据应用等~
机器学习: 一种实现人工智能的方法
机器学习最基本的做法, 是使用算法来解析数据, 从中学习, 然后对事件做出决策和预测.
需要用大量的数据来 "训练", 通过各种算法从数据中学习如何完成任务.
举个例子, 当浏览网上商城时, 经常会出现商品推荐的信息.
这是商城根据往期的购物记录和冗长的收藏清单, 识别出这其中哪些是真正感兴趣, 并且愿意购买的产品.
这样的决策模型, 可以帮助商城为客户提供建议并鼓励产品消费.
[机器学习有三类] :
第一类是无监督学习, 指的是从信息出发自动寻找规律, 并将其分成各种类别, 有时也称 "聚类问题".
第二类是监督学习, 监督学习指的是给历史一个标签, 运用模型预测结果.
如有一个水果, 我们根据水果的形状和颜色去判断到底是香蕉还是苹果, 这就是一个监督学习的例子.
最后一类为强化学习, 是指可以用来支持人们去做决策和规划的一个学习方式, 它是对人的一些动作, 行为产生奖励的回馈机制, 通过这个回馈机制促进学习, 这与人类的学习相似, 所以强化学习是目前研究的重要方向之一.
深度学习: 一种实现机器学习的技术
深度学习是机器学习的一个子领域, 是利用深度的神经网络, 将模型处理得更为复杂, 从而使模型对数据的理解更加深入;
深度学习的核心是, 我们现在有足够快的计算机和足够的数据来实际训练大型神经网络
三者的区别和联系
机器学习是一种实现人工智能的方法, 深度学习是一种实现机器学习的技术.
按照 JB 的理解, 深度学习最终可能会渗透在其他所有机器学习算法;
当然, 并不是说深度学习就是万能的, 也并不一定比机器学习牛逼, 要根据场景来区别;
人工神经网络: 一种机器学习的算法
以 "停止 (Stop) 标志牌" 为例, 将一个停止标志牌图像的所有元素都打碎, 然后用神经元进行 "检查": 八边形的外形, 消防车般的红颜色, 鲜明突出的字母, 交通标志的典型尺寸和静止不动运动特性等等. 神经网络的任务就是给出结论, 它到底是不是一个停止标志牌. 神经网络会根据所有权重, 给出一个经过深思熟虑的猜测 --"概率向量".
神经网络是需要调制, 训练的, 不然会很容易出错的~
ok, 讲到这里, 感觉对这块信息已经有所了解~ 至少知道这些是什么东西了;
简单总结下:
机器学习是一种实现人工智能的方法, 深度学习是一种实现机器学习的技术, 神经网络是一种实现机器学习的算法
TensorFlow 简介
TensorFlow 是 Google 在 2015 年 11 月份开源的人工智能系统 Github 项目地址 https://github.com/tensorflow/tensorflow , 该系统可以被用于语音识别, 图片识别等多个领域.
官网上对 TensorFlow 的介绍是,
一个使用数据流图技术来进行数值计算的开源软件库.
数据流图中的节点, 代表数值运算;
节点节点之间的边, 代表多维数据 (tensors) 之间的某种联系.
可以在多种设备 (含有 CPU 或 GPU) 上通过简单的 API 调用来使用该系统的功能.
TensorFlow 是由 Google Brain 团队的研发人员负责的项目.
什么是数据流图
数据流图是描述有向图中的数值计算过程. 有向图中的节点通常代表数学运算, 但也可以表示数据的输入, 输出和读写等操作; 有向图中的边表示节点之间的某种联系, 它负责传输多维数据(Tensors).
节点可以被分配到多个计算设备上, 可以异步和并行地执行操作. 因为是有向图, 所以只有等到之前的入度节点们的计算状态完成后, 当前节点才能执行操作.
TensorFlow 的特性
灵活性, TensorFlow 不是一个严格的神经网络工具包, 只要你可以使用数据流图来描述你的计算过程, 你可以使用 TensorFlow 做任何事情. 你还可以方便地根据需要来构建数据流图, 用简单的 Python 语言来实现高层次的功能.
可移植性, TensorFlow 可以在任意具备 CPU 或者 GPU 的设备上运行, 你可以专注于实现你的想法, 而不用去考虑硬件环境问题, 你甚至可以利用 Docker 技术来实现相关的云服务.
提高开发效率, TensorFlow 可以提升你所研究的东西产品化的效率, 并且可以方便与同行们共享代码 - 支持语言选项, 目前 TensorFlow 支持 Python 和 C++ 语言.
充分利用硬件资源, 最大化计算性能
TensorFlow 安装
找了很多方式, 最终无奈放弃, 因为都不可行, 依赖的东西太多了, 最后 JB 选择了用 pycharm 来安装 TensorFlow;
pycharm 是 python 的 IDE 软件, 安装库起来比较方便, 而且写代码也不错;
打开 pycharm, 在菜单栏里 flie-settings, 直接搜索 project inter, 选择你用的编译器, 直接点击 +:
输入 tensorflow,install package, 然后就是等待漫长的安装过程了;
当然, 喜欢高难度的同学, 可以看 github 的官网介绍, 祝你好运~
https://github.com/jikexueyuanwiki/tensorflow-zh/blob/master/SOURCE/get_started/os_setup.md
验证
直接 import tensorflow, 运行试试看有没有问题即可; 如果有问题, 会直接报错的~
第一个例子
官网有个例子, 直接拿来用了:
- import tensorflow as tf
- hello = tf.constant("Hello,TensorFlow")
- # 创建了图, 里面放入 hello,TensorFlow
- sess = tf.Session()
- # 定义了一个会话
- print(sess.run(hello))
- # 执行图计算
- a = tf.constant(10)
- b = tf.constant(32)
- # 创建了图, 里面放两个节点, 两个 Constant()ops
- print(sess.run(a+b))
- # 执行图计算, 此处是相加
运行结果:
2018-06-14 18:48:55.967672: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
- b'Hello,TensorFlow'
- 42
上面第一行还是红色的, 虽然不影响结果输出, 但是看着不爽啊;
怎么做? 直接屏蔽就好了~
- import os
- os.environ["TF_CPP_MIN_LOG_LEVEL"]='2'
import os, 加上上面那句即可; 不懂什么意思? 来来来~
- os.environ["TF_CPP_MIN_LOG_LEVEL"]='1' # 这是默认的显示等级, 显示所有信息
- os.environ["TF_CPP_MIN_LOG_LEVEL"]='2' # 只显示 warning 和 Error
- os.environ["TF_CPP_MIN_LOG_LEVEL"]='3' # 只显示 Error
看了上面的例子, 看不出特别的, 先来了解下基础知识吧~
基本使用
需要理解在 TensorFlow 中, 是如何:
将计算流程表示成图;
通过 Sessions 来执行图计算;
将数据表示为 tensors;
使用 Variables 来保持状态信息;
分别使用 feeds 和 fetches 来填充数据和抓取任意的操作结果;
TensorFlow 的基础概念
图(Graph): 用来表示计算任务, 也就我们要做的一些操作.
会话(Session): 建立会话, 此时会生成一张空图; 在会话中添加节点和边, 形成一张图, 一个会话可以有多个图, 通过执行这些图得到结果. 如果把每个图看做一个车床, 那会话就是一个车间, 里面有若干个车床, 用来把数据生产成结果.
Tensor: 用来表示数据, 是我们的原料.
变量(Variable): 用来记录一些数据和状态, 是我们的容器.
feed 和 fetch: 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据. 相当于一些铲子, 可以操作数据.
形象的比喻是: 把会话看做车间, 图看做车床, 里面用 Tensor 做原料, 变量做容器, feed 和 fetch 做铲子, 把数据加工成我们的结果.
图计算
TensorFlow 程序中图的创建类似于一个 [施工阶段],
而在 [执行阶段] 则利用一个 session 来执行图中的节点.
很常见的情况是, 在 [施工阶段] 创建一个图来表示和训练神经网络, 而在 [执行阶段] 在图中重复执行一系列的训练操作.
创建图和运行图
第一个例子那有说明图是怎么创建的, 这里再举例说明下:
- matrix1 = tf.constant([[3.,3.]])
- matrix2 = tf.constant([[2.],[2.]])
- product = tf.matmul(matrix1,matrix2)
- # 创建一个矩阵乘法
- # 默认的图, 有 3 个节点, 两个 constant 和一个 matmul
- sess = tf.Session()
- # 定义一个会话
- result = sess.run(product)
- # 运算乘法, 得到结果
- print(result)
- sess.close()
- # 关闭会话
如果需要使用 GPU, 则如下处理:
- with tf.Session() as sess:
- with tf.device("/cpu:0"):
- matrix1 = tf.constant([[3,3]])
- #这是一行 2 列
- matrix2 = tf.constant([[2],[2]])
- #这个是两行 1 列
- product = tf.matmul(matrix1,matrix2)
- #创建一个矩阵乘法
- #默认的图, 有 3 个节点, 两个 constant 和一个 matmul
- sess = tf.Session()
- #定义一个会话
- result = sess.run(product)
- #运算乘法, 得到结果
- print(result)
- sess.close()
- #关闭会话
device 中的各个字符串含义如下:
"/cpu:0": 你机器的 CPU;
"/gpu:0": 你机器的第一个 GPU;
"/gpu:1": 你机器的第二个 GPU;
常量
tf.constant(value, dtype=None, shape=None, name='Const', verify_shape=False),value 为值, dtype 类型, shape 为张量形状, name 名称, verify_shape 默认 False, 这些项可选. 作用创建一个常量.
- a = tf.constant(2, name="a") # print(a) = 2
- b = tf.constant(2.0, dtype=tf.float32, shape=[2,2], name="b") # 2x2 矩阵, 值为 2
- c = tf.constant([[1, 2], [3, 4]], name="c") # 2x2 矩阵, 值 1,2,3,4
是不是懵逼了? 没事, 留个大概影响就好了~
第二个例子 -- 创建变量
- num = tf.Variable(0,name = "count")
- # 创建一个变量 num
- new_value = tf.add(num,10)
- # 创建一个加法操作, 把当前的数字 + 10
- op = tf.assign(num,new_value)
- # 创建一个赋值操作, 把 new_value 赋值给 num
- with tf.Session() as sess:
- sess.run(tf.global_variables_initializer())
- #初始化变量
- print(sess.run(num))
- for i in range(5):
- #创建一个 for 循环, 循环 5 次
- sess.run(op)
- #执行 op 的赋值操作
- print(sess.run(num))
- #输出 num
输出的结果:
- 0
- 10
- 20
- 30
- 40
- 50
第三个例子 -- 填充
有的时候, 会在声明变量的时候不赋值, 计算的时候才进行赋值, 这个时候 feed 就派上用场了
- input1 = tf.placeholder(tf.float32)
- # 创建一个变量占位符 input1
- input2 = tf.placeholder(tf.float32)
- # 创建一个变量占位符 input2
- mul = tf.multiply(input1, input2)
- # 乘法操作
- with tf.Session() as sess:
- result = sess.run([mul], feed_dict={input1:[7.], input2:[2.]})
- #在运算时, 用 feed 设置两个输入的值
- print(result)
综合例子
- import tensorflow as tf
- import os
- os.environ["TF_CPP_MIN_LOG_LEVEL"]='2'
- import numpy as np
- x_data = np.random.rand(100).astype("float32")
- y_data = x_data * 0.1 + 0.3
- # 模拟生成 100 对数据对, 对应的函数为 y = x * 0.1 + 0.3
- # numpy 是 Python 的一个科学计算库, 提供矩阵运算的功能
- # astype 是转换数组的数据类型
- W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
- b = tf.Variable(tf.zeros([1]))
- # 产生尺寸为 1 的张量
- y = W * x_data + b
- # 指定 w 和 b 变量的取值范围(注意我们要利用 TensorFlow 来得到 w 和 b 的值)
- # tf.random_uniform,TensorFlow 随机值函数, 返回 1 矩阵, 数值产生于 - 1.0 跟 1.0 之间
- loss = tf.reduce_mean(tf.square(y - y_data))
- #reduce_mean 求平均值
- #square 是对里面的值求平方操作
- optimizer = tf.train.GradientDescentOptimizer(0.5)
- # 这个类是实现梯度下降算法的优化器, 第一个参数是要使用的学习率
- train = optimizer.minimize(loss)
- # 最小化均方误差
- init = tf.global_variables_initializer()
- # 初始化 TensorFlow 参数
- sess = tf.Session()
- sess.run(init)
- # 运行数据流图(注意在这一步才开始执行计算过程)
- for step in range(201):
- sess.run(train)
- if step % 20 == 0:
- print(step, sess.run(W), sess.run(b))
- # 观察多次迭代计算时, w 和 b 的拟合值
- # 最好的情况是 w 和 b 分别接近甚至等于 0.1 和 0.3
输出的结果:
- 0 [-0.39065683] [0.66207296]
- 20 [-0.0082044] [0.3498935]
- 40 [0.07841039] [0.30995506]
- 60 [0.09569232] [0.3019863]
- 80 [0.09914052] [0.30039632]
- 100 [0.09982852] [0.30007908]
- 120 [0.09996579] [0.30001578]
- 140 [0.09999318] [0.30000314]
- 160 [0.09999864] [0.30000064]
- 180 [0.09999974] [0.30000013]
- 200 [0.09999995] [0.30000004]
每执行 20 次输出一次数据, 从上面的结果可以看到, 随着次数的增加, w 跟 b 的值越来越靠近 0.1 跟 0.3;
JB 很好奇, 为什么会这这样? 从上面的代码, 没做什么吗? 这个呢? 估计要看 TensorFlow 的源码了, 感兴趣的同学, 看完后记得分享下~
本章就介绍到这里了, 本来还想介绍 hello world 的, 但是考虑整体章节会比较长, 就放下文吧~
小结
来个例行总结, 本文主要讲解人工智能的相关概念, 以及 TensorFlow 的基础用法, 也结合一个例子来证明 TensorFlow 的效果, 至于源码嘛, JB 也不懂, 就是觉得 TensorFlow 很牛逼的感觉~
而我们最终的目的, 是希望用 TensorFlow 来训练自己的模型, 来提高图形验证码的识别率;
谢谢大家~
来源: https://juejin.im/post/5b223b13f265da59645afdb4