python的tensorflow基础

1. TensorFlow简介

TensorFlow是一个开源的、用于机器学习和人工智能的框架。它最初由Google Brain团队开发,作为Google Brain第二代系统,用于实现各种深度学习算法和构建神经网络。TensorFlow使用数据流图表示计算,其中节点表示数学操作,边缘表示多维数组(张量)在节点间流动。TensorFlow提供了许多方便的函数、工具和库,使得使用机器学习和人工智能变得更加易于上手。

2. TensorFlow的基本组件

2.1 张量

在TensorFlow中,张量是一个多维数组,可以表示任何维度的数据。例如,一维的张量可以表示向量,二维的张量可以表示矩阵,更高维的张量可以表示更复杂的数据结构。张量可以用来表示输入数据、输出数据和中间数据。

下面是一个创建张量的示例代码:

import tensorflow as tf

a = tf.constant(1.0)

b = tf.constant(2.0)

c = tf.add(a, b)

print(c) # Tensor("Add:0", shape=(), dtype=float32)

在上面的代码中,我们通过调用tf.constant创建了常量张量a和b。然后,我们将它们相加得到张量c。最后,我们打印出了张量c的值。需要注意的是,我们只是定义了计算图,还没有执行它。因此,打印出的结果是Tensor("Add:0", shape=(), dtype=float32),表示一个未计算的张量。

2.2 变量

变量是一种特殊的张量,它是TensorFlow的状态机制。变量的值可以在计算图的不同操作之间共享,并且可以使用优化器来自动更改其值。

下面是一个使用变量的示例代码:

import tensorflow as tf

W = tf.Variable(tf.zeros([2, 1]))

b = tf.Variable(tf.zeros([1]))

x = tf.placeholder(tf.float32, [None, 2])

y = tf.matmul(x, W) + b

init = tf.global_variables_initializer()

sess = tf.Session()

sess.run(init)

result = sess.run(y, feed_dict={x: [[1, 2]]})

print(result) # [[0.]]

在上面的代码中,我们创建了两个变量W和b。W是一个2行1列的矩阵,b是一个1维张量。然后,我们创建了一个占位符x,它可以接受多个输入。我们使用tf.matmul函数计算矩阵乘法,并将结果添加到b。最后,我们初始化所有变量并创建一个会话进行计算。我们使用feed_dict参数提供占位符的值,并计算出y。

2.3 占位符

占位符是一种使用feed_dict机制向计算图中提供值的机制。占位符可以表示任何类型和大小的数据。

下面是一个使用占位符的示例代码:

import tensorflow as tf

x = tf.placeholder(tf.float32, shape=[None, 2])

y = x + 1

sess = tf.Session()

result = sess.run(y, feed_dict={x: [[1, 2], [3, 4]]})

print(result) # [[2. 3.], [4. 5.]]

在上面的代码中,我们创建了一个占位符x,它可以接受多个输入。我们定义了y为x加上1。然后,我们创建一个会话进行计算。我们使用feed_dict参数提供占位符的值,并计算出y。

3. TensorFlow的计算图

TensorFlow使用计算图来表示计算。在计算图中,节点表示操作,边缘表示数据流。计算图可以分为两个阶段:构建阶段和执行阶段。在构建阶段,我们创建操作和张量,并将它们添加到计算图中。在执行阶段,我们运行计算图并得到输出。

3.1 构建计算图

在TensorFlow中,我们可以使用tf.Graph()创建计算图。默认情况下,TensorFlow会自动创建一个默认计算图,我们可以使用tf.get_default_graph()获取它。

下面是一个构建计算图的示例代码:

import tensorflow as tf

graph = tf.Graph()

with graph.as_default():

a = tf.constant(1)

b = tf.constant(2)

c = tf.add(a, b)

with tf.Session() as sess:

result = sess.run(c)

print(result) # 3

在上面的代码中,我们创建了一个新的计算图,并使用with语句设置为默认计算图。然后,我们创建了两个常量节点a和b,并将它们相加得到节点c。最后,我们创建了一个会话并运行计算图,得到了结果3。

3.2 执行计算图

在TensorFlow中,我们可以使用tf.Session()创建一个会话,并使用sess.run()方法来执行计算图。

下面是一个执行计算图的示例代码:

import tensorflow as tf

a = tf.constant(1)

b = tf.constant(2)

c = tf.add(a, b)

with tf.Session() as sess:

result = sess.run(c)

print(result) # 3

在上面的代码中,我们创建了两个常量节点a和b,并将它们相加得到节点c。然后,我们创建了一个会话并运行计算图,得到了结果3。

4. TensorFlow的模型训练

在TensorFlow中,我们可以使用优化器来训练模型。优化器可以使用梯度下降等算法来最小化成本函数。

4.1 成本函数

成本函数是评估模型的好坏的函数。在训练模型时,我们希望最小化成本函数。

下面是一个使用成本函数的示例代码:

import tensorflow as tf

import numpy as np

x_data = np.random.rand(100).astype(np.float32)

y_data = x_data * 0.1 + 0.3

W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))

b = tf.Variable(tf.zeros([1]))

y = W * x_data + b

loss = tf.reduce_mean(tf.square(y - y_data))

optimizer = tf.train.GradientDescentOptimizer(0.5)

train = optimizer.minimize(loss)

init = tf.global_variables_initializer()

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))

在上面的代码中,我们随机生成100个浮点数作为输入数据x_data。然后,我们用y_data = x_data * 0.1 + 0.3生成对应的输出数据。我们用随机数初始化W和b,并使用tf.reduce_mean(tf.square(y - y_data))计算成本函数。然后,我们使用tf.train.GradientDescentOptimizer(0.5)创建优化器,并创建一个训练操作train来最小化成本函数。我们使用init = tf.global_variables_initializer()初始化所有变量,并使用for循环执行训练过程。每隔20步,我们打印出当前的W和b。

4.2 保存和加载模型

在TensorFlow中,我们可以使用tf.train.Saver()保存和加载模型。

下面是一个保存和加载模型的示例代码:

import tensorflow as tf

W = tf.Variable([.3], tf.float32)

b = tf.Variable([-.3], tf.float32)

x = tf.placeholder(tf.float32)

y = tf.placeholder(tf.float32)

linear_model = W * x + b

loss = tf.reduce_sum(tf.square(linear_model - y))

optimizer = tf.train.GradientDescentOptimizer(0.01)

train = optimizer.minimize(loss)

x_train = [1, 2, 3, 4]

y_train = [0, -1, -2, -3]

init = tf.global_variables_initializer()

sess = tf.Session()

sess.run(init)

saver = tf.train.Saver()

for i in range(1000):

sess.run(train, {x: x_train, y: y_train})

save_path = saver.save(sess, "./model/model.ckpt")

print("Model saved in path: %s" % save_path)

W = tf.Variable(tf.zeros([1]))

b = tf.Variable(tf.zeros([1]))

y = W * x + b

saver = tf.train.Saver()

sess = tf.Session()

saver.restore(sess, "./model/model.ckpt")

print("Model restored.")

print(sess.run(y, {x: [1, 2, 3, 4]}))

在上面的代码中,我们创建了一个变量W和b,并创建了一个线性模型。我们使用tf.train.Saver()创建一个saver对象来保存和加载模型。在训练模型时,我们对W和b进行了多次更新,并使用saver.save()方法保存了模型。在加载模型时,我们重新定义变量W和b,并使用saver.restore()方法加载了模型。注意,加载模型后,我们不能再执行训练操作。最后,我们使用sess.run()方法计算模型的输出。

5. 使用TensorFlow进行文本生成

在这个示例中,我们使用RNN(循环神经网络)来生成新的文本内容。RNN是一种递归神经网络,它可以处理序列输入。

5.1 数据预处理

在这个示例中,我们使用莎士比亚的作品来生成新的文本内容。我们将文本拆分成长度为seq_length的片段,并将每个片段映射到一个数字。这样,我们就可以将输入数据表示为数字序列。

下面是一个数据预处理的示例代码:

import numpy as np

data = open('shakespeare.txt', 'r').read()

chars = list(set(data))

data_size, vocab_size = len(data), len(chars)

char_to_ix = { ch:i for i,ch in enumerate(chars) }

ix_to_char = { i:ch for i,ch in enumerate(chars) }

seq_length = 50

num_seqs = int(len(data) / seq_length)

X_seqs = []

y_seqs = []

for i in range(num_seqs):

X_seq = data[i*seq_length:(i+1)*seq_length]

y_seq = data[i*seq_length+1:(i+1)*seq_length+1]

X_seq_num = [char_to_ix[ch] for ch in X_seq]

y_seq_num = [char_to_ix[ch] for ch in y_seq]

X_seqs.append(X_seq_num)

y_seqs.append(y_seq_num)

# Convert X_seqs and y_seqs to numpy arrays

X = np.array(X_seqs)

y = np.array(y_seqs)

在上面的代码中,我们首先读取文本数据,然后创建一个字符到数字的映射char_to_ix和数字到字符的映射ix_to_char。我们使用seq_length=50将文本拆分成长度为50的片段,并将每个片段映射到一个数字。这样,我们就可以使用数字序列来表示数据。最后,我们将X_seqs和y_seqs转换为numpy数组。

5.2 构建模型

在这个示例中,我们使用一个多层RNN来生成新的文本内容。我们使用一个单元大小为128的LSTM层,并在顶部添加一个输出层。

下面是一个构建模型的示例代码:

import tensorflow as tf

from tensorflow.contrib import rnn

batch_size = 100

dropout = 0.5

epochs = 100

learning_rate = 0.01

num_layers = 3

num_units = 128

X_placeholder = tf.placeholder(tf.int32, shape=[None, seq_length])

y_placeholder = tf.placeholder(tf.int32, shape=[None, seq_length])

embedding = tf.Variable(tf.random_uniform([vocab_size, num_units], -1.0, 1.0))

inputs = tf.nn.embedding_lookup(embedding, X_placeholder)

lstm_cells = [rnn.BasicLSTMCell(num_units) for _ in range(num_layers)]

stacked_lstm = rnn.MultiRNNCell(lstm_cells, state_is_tuple=True)

initial_state = stacked_lstm.zero_state(batch_size, dtype=tf.float32)

outputs, final_state = tf.nn.dynamic_rnn(stacked_lstm, inputs, initial_state=initial_state)

logits = tf.layers.dense(outputs, vocab_size)

predictions = tf.argmax(logits, axis=2)

loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=y_placeholder))

optimizer = tf.train.AdamOptimizer(learning_rate).minimize(loss)

init = tf.global_variables_initializer()

sess = tf.Session()

sess.run(init)

for epoch in range(epochs):

epoch_loss = 0

for i in range(num_seqs // batch_size):

X_batch = X[i*batch_size:(i+1)*batch_size]

y_batch = y[i*batch_size:(i+1)*batch_size]

_, batch_loss = sess.run([optimizer, loss], feed_dict={X_placeholder: X_batch, y_placeholder: y_batch})

epoch_loss += batch_loss

epoch_loss /= (num_seqs // batch_size)

print('Epoch: {:d}, Loss: {:.4f}'.format(epoch+1, epoch_loss))

在上面的代码中,我们使用tf.nn.embedding_lookup函数将输入数据转换为嵌入表示。然后,我们创建一个多层LSTM网络,并使用tf.nn.dynamic_rnn函数将其应用于输入数据。我们添加一个全连接层来预测下一个字符。我们使用tf.argmax函数选择预测的字符。最后,我们使用tf.nn.sparse_softmax_cross_entropy_with_logits函数计算损失,并使用Adam优化器来最小化损失。

5.3 训练模型

在训练模型时,我们需要使用batch_size=100和epochs=100来控制训练过程。我们可以使用tf.Session()创建一个会话,并使用sess.run()方法来执行训练操作。

下面是一个训练模型的示例代码:

import random

temperature = 0.6

input_str = 'shall i compare thee to a summer\'s day?\n'

generated_str = input_str

state = sess.run(stack_lstm.zero_state(1, tf.float32))

for i in range(1000):

X_batch = np.zeros((1, seq_length))

for j, ch in enumerate(input_str):

X_batch[0, j] = char_to_ix[ch]

feed_dict = {X_placeholder: X_batch, initial_state: state}

state, prediction = sess.run([