基于Google Colab的tensorflow 1.8+深度学习教程

基于Google Colab的 tensorflow 1.8+深度学习教程

        今天是2019年5月10号,小亮最近折腾了两天,主要基于Google Colab实现了一下tensorflow 1.8的基础教程,至于说为什么基于Google Colab,大家可以看我上一篇博文:Deep Learning时代最好用的云GPU——Google Colab (免费提供 Tesla T4 GPU) 话不多说,我们进入今天的课堂!如果你对NLP,对深度学习感兴趣,欢迎和小亮交流,联系方式如下。

笔者信息:Next_Legend QQ:1219154092 机器学习 自然语言处理 深度学习 统计概率论

小亮的博客:https://legendtianjin.github.io/NextLegend.github.io/ ——2019.5.10于北洋


一、为什么是基于tensorflow 1.8?

       这是因为tensorflow 1.8版本是一个分水岭!!!什么分水岭呢?(先别着急,答案在后面。)2018 年 3 月 30 日,Google 在加州山景城举行了第二届 TensorFlow Dev Summit 开发者峰会,并宣布正式发布 TensorFlow 1.8 版本。这一具有里程碑式意义的新版本发布。众多新功能的加入和支持展示了 TensorFlow 的雄心壮志,同时早在 2017 年秋就开始测试的Eager Execution(动态图机制)在这一版本中终于正式加入,并成为了入门 TensorFlow 的官方推荐模式。

       The easiest way to get started with TensorFlow is using Eager Execution. ——https://www.tensorflow.org/tutorials

       在此之前,TensorFlow 所基于的传统 Graph Execution 的弊端,如入门门槛高、调试困难、灵活性差、无法使用 Python 原生控制语句等早已被开发者诟病许久。一些新的基于动态图机制的深度学习框架(如 PyTorch)也横空出世,并以其易用性和快速开发的特性而占据了一席之地。尤其是在学术研究等需要快速迭代模型的领域,PyTorch 等新兴深度学习框架已经成为主流。然而,目前市面上相关的 TensorFlow 相关的中文技术书籍及资料仍然基于传统的 Graph Execution 模式,让不少初学者(尤其是大学生)望而却步。由此,在 TensorFlow 正式支持 Eager Execution 之际,有必要重点介绍一下Eager Execution(动态图机制,帮助初学者及需要快速迭代模型的研究者,以一个全新的角度快速入门 TensorFlow。

二、tensorflow 1.8+ 参考教程

        小亮这里其实也是参考了一些资料,放在这里供大家学习参考。(以下资料小亮均放在私人博客里,欢迎大家前往下载。)

        小亮的博客:https://legendtianjin.github.io/NextLegend.github.io/

        TensorFlow官网教程

        简单粗暴 TensorFlow

        2018TensorFlow中文版

        2018TensorFlow英文版

三、tensorflow 1.8+基础教程

       下面我们就开始tensorflow基础教程的学习!因为tensorflow 每次的更新都会更改很多函数,所以大家不可避免的会遇到很多bug,刚开始要静下心来,慢慢找到问题,在下面的教程中小亮就遇到一个bug,足足想了两天,才解决,切身体会:山穷水尽之时,便是柳暗花明之时!

3.1、基于Google Colab的云GPU配置

        虽然Google Colab提供给我们免费的GPU和TPU使用,但是每天免费使用时间为12小时,所以如果我们使用Colab的话,每天的第一件事就是配置相关文件,其实看上去有点麻烦,5秒钟就可以完成相关配置。(步骤如下:)敲入以下代码,会出现一个链接,点击链接然后授权Google账号(没有的话自己注册一个就好),复制粘贴授权码就可以了。(授权的目的是为了使Colab和Google云端硬盘通信,方便数据文件和代码文件的管理。)

from google.colab import drive
drive.mount('/content/drive/')

基于Google Colab的tensorflow 1.8+深度学习教程_第1张图片

3.2、查看tensorflow版本号以及安装tensorflow 1.8

        为了增加阅读的流畅性,后面小亮尽量使用代码讲解,少一些文字性的描述。大家尽快去尝试,出现问题了先自己解决,然后再请教别人,欢迎大家和小亮交流。

       (1)查看tensorflow版本号

import tensorflow as tf
tf.__version__

       (2)安装tensorflow 1.8

!pip install tensorflow==1.8.0rc 

       最后再次查看tensorflow版本号,发现是我们安装的版本

基于Google Colab的tensorflow 1.8+深度学习教程_第2张图片

3.3、第一个tensorflow程序

        TensorFlow Eager Execution(动态图)模式在TensorFlow 1.8版本中开始引入,相比传统的Graph Execution模式有了很大的进步。该模式能够快速调试,使用Python原生控制语句,能够大大降低学习的门槛。作为未来TensorFlow 2.0版本的默认模式,有必要从现在就开始熟悉。本文作为一个入门简介,将简要介绍TensorFlow安装以及如何使用Eager Execution模式。

import tensorflow as tf
# TensorFlow 1.8版本只是引入了该模式,并没有作为默认模式。使用的时候需要显示申明
# tf.enable_eager_execution()          #TensorFlow Eager Execution(动态图)模式在TensorFlow 1.8版本中开始引入,   通过tf.enable_eager_execution() 启动动态图模式
# tfe = tf.contrib.eager
A = tf.constant([[1, 2], [3, 4]])
B = tf.constant([[5, 6], [7, 8]])
C = tf.matmul(A, B)
print(C)

3.4、TensorFlow 自动求导机制来计算导数。

        (1)以下代码展示了如何使用 tf.GradientTape() 计算函数 y(x) = x^2 在 x = 3 时的导数。

import tensorflow as tf
# tf.enable_eager_execution()
x = tf.get_variable('x', shape=[1], initializer=tf.constant_initializer(3.))  #这里 x 是一个初始化为 3 的 变量(Variable),使用 tf.get_variable() 声明, 初始化为float32 类型的 3.

# tf.GradientTape() 是一个自动求导的记录器,在 tf.GradientTape() 的上下文内,所有计算步骤都会被记录以用于求导。
with tf.GradientTape() as tape:
    y = tf.square(x)
y_grad = tape.gradient(y, x) # 计算 y 关于 x 的导数

print([y.numpy(), y_grad.numpy()])

在这里插入图片描述

        (2)在机器学习中,更加常见的是对多元函数求偏导数,以及对向量或矩阵的求导。以下代码展示了如何使用 tf.GradientTape() 计算函数 L(w, b) = ∥Xw+bby∥^2 在 w = (1, 2)^T, b = 1 时分别对 w, b 的偏导数。其中 X = [1 2 3 4], y =[1 2 ]

X = tf.constant([[1., 2.], [3., 4.]])   #Python 中可以使用整数后加小数点表示将该整数定义为浮点数类型。例如 3. 代表浮点数 3.0
y = tf.constant([[1.], [2.]])

w = tf.get_variable('w', shape=[2, 1], initializer=tf.constant_initializer([[1.], [2.]]))
b = tf.get_variable('b', shape=[1], initializer=tf.constant_initializer([1.]))

with tf.GradientTape() as tape:
    L = 0.5 * tf.reduce_sum(tf.square(tf.matmul(X, w) + b - y))       #tf.reduce_sum() 操作代表对输入张量的所有元素求和,输出一个形状为空的纯量张量
w_grad, b_grad = tape.gradient(L, [w, b]) # 计算 L(w, b) 关于 w, b 的偏导数

print([L.numpy(), w_grad.numpy(), b_grad.numpy()])

在这里插入图片描述

3.5、基础示例:多层感知机(MLP)

        我们从编写一个最简单的 多层感知机 (Multilayer Perceptron, MLP)开始,介绍 TensorFlow 的模型编写 方式。这里,我们使用多层感知机完成 MNIST 手写体数字图片数据集 [LeCun1998] 的分类任务。

import tensorflow as tf
import numpy as np
tf.enable_eager_execution
#先进行预备工作,实现一个简单的 DataLoader 类来读取 MNIST 数据集数据。
class DataLoader():
    def __init__(self):
        mnist = tf.contrib.learn.datasets.load_dataset("mnist")
        self.train_data = mnist.train.images # np.array [55000,␣,→784]
        self.train_labels = np.asarray(mnist.train.labels, dtype=np.int32) # np.array [55000] of␣,→int32
        self.eval_data = mnist.test.images # np.array [10000,␣,→784]
        self.eval_labels = np.asarray(mnist.test.labels, dtype=np.int32) # np.array [10000] of␣ ,→int32
    def get_batch(self, batch_size):
        index = np.random.randint(0, np.shape(self.train_data)[0], batch_size)
        return self.train_data[index, :], self.train_labels[index]
    
    
    
class MLP(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)
        self.dense2 = tf.keras.layers.Dense(units=10)
        
    def call(self, inputs):
        x = self.dense1(inputs)
        x = self.dense2(x)
        return x
    
    def predict(self, inputs):
        logits = self(inputs)
        return tf.argmax(logits, axis=-1)
    
#定义一些模型超参数:
num_batches = 1000
batch_size = 50
learning_rate = 0.001

#实例化模型,数据读取类和优化器
model = MLP()
data_loader = DataLoader()
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)

#具体代码实现如下:
for batch_index in range(num_batches):
    X, y = data_loader.get_batch(batch_size)
    with tf.GradientTape() as tape:
        y_logit_pred = model(tf.convert_to_tensor(X))
        loss = tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_logit_pred)
        print("batch %d: loss %f" % (batch_index, loss.numpy)
    grads = tape.gradient(loss, model.variables)
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
    
    
#接下来,我们使用验证集测试模型性能。具体而言,比较验证集上模型预测的结果与真实结果,输出预测正确的样本数占总样本数的比例:
num_eval_samples = np.shape(data_loader.eval_labels)[0]
y_pred = model.predict(data_loader.eval_data).numpy()
print("test accuracy: %f" % (sum(y_pred == data_loader.eval_labels) / num_eval_samples))

3.6、卷积神经网络(CNN)

        这里,我们使用卷积神经网络(CNN)完成 MNIST 手写体数字图片数据集 [LeCun1998] 的分类任务。

import tensorflow as tf
import numpy as np

tf.enable_eager_execution?

class DataLoader():
    def __init__(self):
        mnist = tf.contrib.learn.datasets.load_dataset("mnist")
        self.train_data = mnist.train.images # np.array [55000,␣,→784]
        self.train_labels = np.asarray(mnist.train.labels, dtype=np.int32) # np.array [55000] of␣,→int32
        self.eval_data = mnist.test.images # np.array [10000,␣,→784]
        self.eval_labels = np.asarray(mnist.test.labels, dtype=np.int32) # np.array [10000] of␣ ,→int32
    def get_batch(self, batch_size):
        index = np.random.randint(0, np.shape(self.train_data)[0], batch_size)
        return self.train_data[index, :], self.train_labels[index]
    


class CNN(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = tf.keras.layers.Conv2D(
            filters=32, # 卷积核数目
            kernel_size=[5, 5], # 感受野大小
            padding="same", # padding 策略
            activation=tf.nn.relu # 激活函数
        )
        self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
        self.conv2 = tf.keras.layers.Conv2D(
            filters=64,
            kernel_size=[5, 5],padding="same",activation=tf.nn.relu)
        self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
        self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
        self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu)
        self.dense2 = tf.keras.layers.Dense(units=10)
        
        
    def call(self, inputs):
        inputs = tf.reshape(inputs, [-1, 28, 28, 1])
        x = self.conv1(inputs) # [batch_size, 28, 28, 32]
        x = self.pool1(x) # [batch_size, 14, 14, 32]
        x = self.conv2(x) # [batch_size, 14, 14, 64]
        x = self.pool2(x) # [batch_size, 7, 7, 64]
        x = self.flatten(x) # [batch_size, 7 * 7 * 64]
        x = self.dense1(x) # [batch_size, 1024]
        x = self.dense2(x) # [batch_size, 10]
        return x

    def predict(self, inputs):
        logits = self(inputs)
        return tf.argmax(logits, axis=-1)
        
        
#定义一些模型超参数:
num_batches = 100
batch_size = 50
learning_rate = 0.001

#实例化模型,数据读取类和优化器
model = CNN()
data_loader = DataLoader()
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)

#具体代码实现如下:
for batch_index in range(num_batches):
    X, y = data_loader.get_batch(batch_size)
    with tf.GradientTape() as tape:
        y_logit_pred = model(tf.convert_to_tensor(X))
        loss = tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_logit_pred)
        print("batch %d: loss %f" % (batch_index, loss.numpy()))
    grads = tape.gradient(loss, model.variables)
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
    
    
#接下来,我们使用验证集测试模型性能。具体而言,比较验证集上模型预测的结果与真实结果,输出预测正确的样本数占总样本数的比例:
num_eval_samples = np.shape(data_loader.eval_labels)[0]
y_pred = model.predict(data_loader.eval_data).numpy()
print("test accuracy: %f" % (sum(y_pred == data_loader.eval_labels) / num_eval_samples))

基于Google Colab的tensorflow 1.8+深度学习教程_第3张图片

3.7、循环神经网络(RNN)

        循环神经网络(Recurrent Neural Network, RNN)是一种适宜于处理序列数据的神经网络,被广泛用于语言模型、文本生成、机器翻译等。这里,我们使用 RNN 来进行尼采风格文本的自动生成。这个任务的本质其实预测一段英文文本的接续字母的概率分布。

import tensorflow as tf
import numpy as np

tf.enable_eager_execution



class DataLoader():
    def __init__(self):
        path = tf.keras.utils.get_file('nietzsche.txt',
                                       origin='https://s3.amazonaws.com/text-datasets/nietzsche.txt')
        with open(path, encoding='utf-8') as f:
            self.raw_text = f.read().lower()
        self.chars = sorted(list(set(self.raw_text)))
        self.char_indices = dict((c, i) for i, c in enumerate(self.chars))
        self.indices_char = dict((i, c) for i, c in enumerate(self.chars))
        self.text = [self.char_indices[c] for c in self.raw_text]

    def get_batch(self, seq_length, batch_size):
        seq = []
        next_char = []
        for i in range(batch_size):
            index = np.random.randint(0, len(self.text) - seq_length)
            seq.append(self.text[index:index + seq_length])
            next_char.append(self.text[index + seq_length])
        return np.array(seq), np.array(next_char)  # [num_batch, seq_length], [num_batch]


class RNN(tf.keras.Model):
    def __init__(self, num_chars):
        super().__init__()
        self.num_chars = num_chars
        self.cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=256)
        self.dense = tf.keras.layers.Dense(units=self.num_chars)
      
    
    def predict(self, inputs, temperature=1.):
        batch_size, _ = tf.shape(inputs)
        logits = self(inputs)
        prob = tf.nn.softmax(logits / temperature).numpy()
        return np.array([np.random.choice(self.num_chars, p=prob[i, :])
                            for i in range(batch_size.numpy())])

    def call(self, inputs):
        batch_size, seq_length = tf.shape(inputs)
        inputs = tf.one_hot(inputs, depth=self.num_chars)  # [batch_size, seq_length, num_,→chars]
        state = self.cell.zero_state(batch_size=batch_size, dtype=tf.float32)
        for t in range(seq_length.numpy()):
            output, state = self.cell(inputs[:, t, :], state)
        output = self.dense(output)
        return output

#定义一些模型超参数:
num_batches = 3000
batch_size = 50
seq_length = 20
learning_rate = 0.001


data_loader = DataLoader()
model = RNN(len(data_loader.chars))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)

for batch_index in range(num_batches):
    X, y = data_loader.get_batch(seq_length, batch_size)
    with tf.GradientTape() as tape:
        y_logit_pred = model(X)
        loss = tf.losses.sparse_softmax_cross_entropy(labels=y, logits=y_logit_pred)
        print("batch %d: loss %f" % (batch_index, loss.numpy()))
    grads = tape.gradient(loss, model.variables)
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))



X_, _ = data_loader.get_batch(5, 1)
for diversity in [0.2, 0.5, 1.0, 1.2]:
    X = X_
    print("diversity %f:" % diversity)
    for t in range(400):
        y_pred = model.predict(X,diversity)
        print(data_loader.indices_char[y_pred[0]], end='', flush=True)
        X = np.concatenate([X[:, 1:], np.expand_dims(y_pred, axis=1)], axis=-1)

基于Google Colab的tensorflow 1.8+深度学习教程_第4张图片

3.8、深度强化学习(DRL)

        强化学习 (Reinforcement learning,RL)强调如何基于环境而行动,以取得最大化的预期利益。结合了深度学习技术后的强化学习更是如虎添翼。这两年广为人知的 AlphaGo 即是深度强化学习的典型应用。这里,我们使用深度强化学习玩 CartPole(平衡杆)游戏。简单说,我们需要让模型控制杆的左右运动,以让其一直保持竖直平衡状态。

import gym
env = gym.make("CartPole-v1")
observation = env.reset()
for _ in range(1000):
  env.render()
  action = env.action_space.sample() # your agent here (this takes random actions)
  observation, reward, done, info = env.step(action)

  if done:
    observation = env.reset()
env.close()

基于Google Colab的tensorflow 1.8+深度学习教程_第5张图片

你可能感兴趣的:(tensorflow)