TensorFlow简介
TensorFlow是Google开发的一款神经网络的Python外部的结构包, 也是一个采用数据流图来进行数值计算的开源软件库.TensorFlow 让我们可以先绘制计算结构图, 也可以称是一系列可人机交互的计算操作, 然后把编辑好的Python文件 转换成 更高效的C++, 并在后端进行计算.
TensorFlow安装
Docker安装
Dock安装
Docker安装请参考实验室GPU服务器部署教程
Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组,参考:docker docs
1 | sudo usermod -aG docker $USER |
安装NVIDIA-Docker
安装完成docker并检查安装正确(能跑出来hello-world)后,如果需要docker容器中有gpu支持,需要再安装NVIDIA-Docker,同样找到并打开该项目的主页:
1 | NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs |
可以看到在Quick start小节,根据系统版本执行命令:
Ubuntu 14.04/16.04/18.04, Debian Jessie/Stretch:
1 | # If you have nvidia-docker 1.0 installed: we need to remove it and all existing GPU containers |
CentOS 7 (docker-ce), RHEL 7.4/7.5 (docker-ce), Amazon Linux 1/2:
If you are not using the official docker-ce package on CentOS/RHEL, use the next section.
1 | # If you have nvidia-docker 1.0 installed: we need to remove it and all existing GPU containers |
If yum reports a conflict on /etc/docker/daemon.json with the docker package, you need to use the next section instead.
CentOS 7 (docker), RHEL 7.4/7.5 (docker):
1 | # If you have nvidia-docker 1.0 installed: we need to remove it and all existing GPU containers |
上面最后一条命令是检查是否安装成功,安装成功,则会显示关于GPU的信息。
然后在执行下面这句,默认用nvdia-docker替代docker命令:
1 | echo 'alias docker=nvidia-docker' >> ~/.bashrc |
下载使用TensorFlow镜像
打开dockerhub关于tensorflow的页面:
1 | tensorflow/tensorflow – Docker Hub |
根据需要的版本下载tensorflow镜像并开启tensorflow容器:
CPU版本
1 | docker run -it -p 8888:8888 tensorflow/tensorflow |
GPU版本
1 | nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu |
如何使用,执行以上命令的结果类似如下:
1 | $ nvidia-docker run -it -p 8888:8888 tensorflow/tensorflow:latest-gpu |
其中看到有个网址:
1 | http://localhost:8888/?token=8f90cc7b9ad6ccc4f36f53f347c7a314220bbcb82dd416ea |
每个人的网址在token=后面的内容是不一样的,现在我们打开浏览器,输入网址:
1 | http://localhost:8888/ |
输入刚刚token后面的值后,点击第一个1_hello_tensorflow.ipynb,然后可以选择执行所有代码.
常用命令:
1 | docker image pull library/hello-world |
上面代码中,docker image pull是抓取 image 文件的命令。library/hello-world是 image 文件在仓库里面的位置,其中library是 image 文件所在的组,hello-world是 image 文件的名字。
1 | docker image ls |
抓取成功以后,就可以在本机看到这个 image 文件了。运行这个 image 文件:
1 | docker container run hello-world |
docker container run命令会从 image 文件,生成一个正在运行的容器实例。
注意,docker container run命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的docker image pull命令并不是必需的步骤。
有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。
1 | docker container run -it ubuntu bash |
对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止。
1 | docker container kill [containID] |
image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。
1 | # 列出本机正在运行的容器 |
上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,比如上一节终止容器运行的docker container kill命令。
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除。
1 | docker container rm [containerID] |
运行上面的命令之后,再使用docker container ls —all命令,就会发现被删除的容器文件已经消失了。
创建tensorflow docker容器:
1 | docker container run --name [name] -it -p 8888:8888 tensorflow/tensorflow:latest-gpu /bin/bash |
启动docker:
1 | docker start [name] |
进入docker:
1 | docker attach [name] |
重命名docker:
1 | docker rename old_name new_name |
如何进入正在执行的 docker container
docker attach
这个是官方提供的一种方法。
测试,首先启动一个container:
1 | $ docker run -i -t ubuntu bash |
不要退出,打开另一个终端:
1 | $ docker ps |
这样就连接进去了。这时候如果我们输入一些命令,就能看到在两个终端都有显示和输出。这种方式有比较大的局限性,如果知道了entrypoint或者有程序正在执行,通过docker attach进入之后是不能执行操作的,一个终端退出之后整个container就终止了。不推荐使用这种方式。
lxc-attach
如果使用这种方式,首先要保证docker是以lxc方式启动的,具体可以这样做:
修改/etc/default/docker增加DOCKER_OPTS=”-e lxc”
重启docker服务sudo service docker restart
启动container的方式和之前一样:
1 | $ docker run -i -t ubuntu bash |
进入container可以这样:
1 |
|
这种方式还是很方便的。前提是需要重启docker服务以lxc的方式执行,进入container之后会有一个终端可以执行命令,不影响正在执行的程序。
nsenter
如果docker不是以lxc方式启动的,这时候还想进入一个正在执行的container的话,可以考虑使用nsenter
这个程序的安装方式很独特,使用docker进行安装:
1 | $ docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter |
使用方法也很简单,首先你要进入的container的PID:
1 | $ PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>) |
然后就可以用这个命令进入container了:
1 | $ nsenter --target $PID --mount --uts --ipc --net --pid |
为了使用方便可以写一个脚本自动完成:
1 | $ cat /bin/docker_enter |
这样每次要进入某个container只需要执行docker_enter
ssh
这个原理也很简单,在container里面启动ssh服务,然后通过ssh的方式去登陆到container里面,不推荐这种方式,主要是配置ssh登陆比较繁琐,开启ssh服务也会耗费资源,完全没有必要。
TensorFlow安装方式一
下载镜像
1
docker pull tensorflow/tensorflow
创建Tensorflow容器
1
2
3
4
5
6docker run --name my-tensorflow -it -p 8888:8888 -v ~/tensorflow:/test/data tensorflow/tensorflow
# --name:创建的容器名,即my-tensorflow
# -it:保留命令行运行
# p 8888:8888:将本地的8888端口和http://localhost:8888/映射
# -v ~/tensorflow:/test/data:将本地的~/tensorflow挂载到容器内的/# test/data下
# tensorflow/tensorflow :默认是tensorflow/tensorflow:latest,指定使用的镜像拷贝带token的URL在浏览器打开
1
http://[all ip addresses on your system]:8888/?token=649d7cab1734e01db75b6c2b476ea87aa0b24dde56662a27
显示Jupyter Notebook,Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本。示例中已经显示了Tensorflow的入门教程,点开一个可以看见。
关闭容器
1
docker stop my-tensortflow
再次打开
1
docker start my-tensortflow
TensorFlow安装方式二
下载镜像
1
docker pull tensorflow/tensorflow
创建Tensorflow容器
1
2docker run -it --name bash_tensorflow tensorflow/tensorflow /bin/bash
# 这样我们就创建了名为bash_tensorflow的容器
start命令启动容器
1
docker start bash_tensorflow
再连接上容器
1
2docker attach bash_tensorflow
# 可以看到我们用终端连接上了容器,和操作Linux一样了。
Pip安装
Linux 和 MacOS
1 | # Ubuntu/Linux 64-位 系统的执行代码: |
CPU 版
1
2
3
4
5# python 2+ 的用户:
$ pip install tensorflow
# python 3+ 的用户:
$ pip3 install tensorflowGPU 版
1
2
3
4
5
6
7$ sudo apt-get install libcupti-dev
$ sudo apt-get install python-pip python-dev # for Python 2.7
$ sudo apt-get install python3-pip python3-dev # for Python 3.n
$ pip install tensorflow # Python 2.7; CPU support (no GPU support)
$ pip3 install tensorflow # Python 3.n; CPU support (no GPU support)
$ pip install tensorflow-gpu # Python 2.7; GPU support
$ pip3 install tensorflow-gpu # Python 3.n; GPU support
测试
1
import tensorflow
TensorFlow 教程
Session 会话控制
参考:
Session 是 Tensorflow 为了控制,和输出文件的执行的语句. 运行 session.run() 可以获得你要得知的运算结果, 或者是你所要运算的部分.
例子讲解:建立两个 matrix ,输出两个 matrix 矩阵相乘的结果。
1 | import tensorflow as tf |
因为 product 不是直接计算的步骤, 所以我们会要使用 Session 来激活 product 并得到计算结果. 有两种形式使用会话控制 Session 。
1 | # method 1 |
Variable 变量
参考:
在 Tensorflow 中,定义了某字符串是变量,它才是变量。定义语法: state = tf.Variable()
1 | import tensorflow as tf |
如果你在 Tensorflow 中设定了变量,那么初始化变量是最重要的!!所以定义了变量以后, 一定要定义 init = tf.initialize_all_variables() .
到这里变量还是没有被激活,需要再在 sess 里, sess.run(init) , 激活 init 这一步.
1 | # 如果定义 Variable, 就一定要 initialize |
注意:直接 print(state) 不起作用!!
一定要把 sess 的指针指向 state 再进行 print 才能得到想要的结果!
Placeholder 传入值
参考:
placeholder 是 Tensorflow 中的占位符,暂时储存变量.
Tensorflow 如果想要从外部传入data, 那就需要用到 tf.placeholder(), 然后以这种形式传输数据 sess.run(*, feed_dict={input: }).
示例:
1 | import tensorflow as tf |
接下来, 传值的工作交给了 sess.run() , 需要传入的值放在了feed_dict={} 并一一对应每一个 input. placeholder 与 feed_dict={} 是绑定在一起出现的。
1 | with tf.Session() as sess: |
建造神经网络
参考:
add_layer 功能
1 | import tensorflow as tf |
导入数据
构建所需的数据。 这里的x_data和y_data并不是严格的一元二次函数的关系,因为我们多加了一个noise,这样看起来会更像真实情况。
1 | x_data = np.linspace(-1,1,300, dtype=np.float32)[:, np.newaxis] |
利用占位符定义我们所需的神经网络的输入。 tf.placeholder()就是代表占位符,这里的None代表无论输入有多少都可以,因为输入只有一个特征,所以这里是1。
1 | xs = tf.placeholder(tf.float32, [None, 1]) |
接下来,我们就可以开始定义神经层了。 通常神经层都包括输入层、隐藏层和输出层。这里的输入层只有一个属性, 所以我们就只有一个输入;隐藏层我们可以自己假设,这里我们假设隐藏层有10个神经元; 输出层和输入层的结构是一样的,所以我们的输出层也是只有一层。 所以,我们构建的是——输入层1个、隐藏层10个、输出层1个的神经网络。
搭建网络
利用之前的add_layer()函数,这里使用 Tensorflow 自带的激励函数tf.nn.relu。
1 | l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu) |
接着,定义输出层。此时的输入就是隐藏层的输出——l1,输入有10层(隐藏层的输出层),输出有1层。
1 | prediction = add_layer(l1, 10, 1, activation_function=None) |
计算预测值prediction和真实值的误差,对二者差的平方求和再取平均。
1 | loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction), |
接下来,是很关键的一步,如何让机器学习提升它的准确率。tf.train.GradientDescentOptimizer()中的值通常都小于1,这里取的是0.1,代表以0.1的效率来最小化误差loss。
1 | train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss) |
使用变量时,都要对它进行初始化,这是必不可少的。
1 | # init = tf.initialize_all_variables() # tf 马上就要废弃这种写法 |
定义Session,并用 Session 来执行 init 初始化步骤。 (注意:在tensorflow中,只有session.run()才会执行我们定义的运算。)
1 | sess = tf.Session() |
训练
机器学习的内容是train_step, 用 Session 来 run 每一次 training 的数据,逐步提升神经网络的预测准确性。 (注意:当运算要用到placeholder时,就需要feed_dict这个字典来指定输入。)
1 | for i in range(1000): |
每50步我们输出一下机器学习的误差。
1 | if i % 50 == 0: |
1 | 0.021204619 |