专栏首页光城(guangcity)TensorFlow线性回归与逻辑回归实战

TensorFlow线性回归与逻辑回归实战

TensorFlow线性回归与逻辑回归实战

议程

  • Review
  • Linear regression on birth/life data
  • Control Flow
  • tf.data
  • Optimizers, gradients
  • Logistic regression on MNIST
  • Loss functions

一、TensorFlow线性回归


回顾

计算图

TensorFlow将计算的定义与其执行分开

阶段1:组装图表

阶段2:使用会话在图中执行操作。

TensorBoard

import tensorflow as tf
x = 2
y = 3
add_op = tf.add(x, y)
mul_op = tf.multiply(x, y)
useless = tf.multiply(x, add_op)
pow_op = tf.pow(add_op, mul_op)
writer=tf.summary.FileWriter('./graphs',tf.get_default_graph())
with tf.Session() as sess:
    z = sess.run(pow_op)

tf.constant and tf.Variable

常量值存储在图形定义中

会话分配内存来存储变量值

tf.placeholder and feed_dict

使用字典(feed_dict)将值提供给占位符

易于使用但性能不佳

避免懒加载

  • 分离图形的组合和执行操作
  • 使用Python属性确保函数仅在第一次调用时加载

在TensorFlow中的线性回归

数据与模型概要

建模之间的线性关系:

  • 因变量Y.
  • 解释变量X.

世界发展指标数据集

  • X: 出生率
  • Y: 预期寿命

190 国家

想要:找到X和Y之间的线性关系,从X预测Y.

模型:参考: Y_predicted = w * X + b

均方误差: E[(y - y_predicted)2]

所需数据与代码:

data/birth_life_2010.txt
examples/03_linreg_starter.py

阶段1:组装我们的图表

第一步:读数据

import os 
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import numpy as np
%matplotlib inline
import pandas as pd
第一种方式读取(官方)
def read_data(filename):
    '''
    读取birth_life_2010.txt 数据
    data:返回numpy数组数据
    n_samples:例子的数量
    '''
    # 去掉head
    text = open(filename, 'r').readlines()[1:]
    # 去掉每一行末尾的换行符\n,并以制表符\t进行分隔
    data = [line[:-1].split('\t') for line in text]
    # 提取出生率
    births = [float(line[1]) for line in data]
    # 提取预期寿命
    lifes = [float(line[2]) for line in data]
    # 变成[(),()]数据
    data = list(zip(births, lifes))
    # 统计数据量
    n_samples = len(data)
    # 数据转换为numpy的ndarray类型
    data = np.asarray(data, dtype=np.float32)
    return data, n_samples
data,n_samples=read_data('birth_life_2010.txt')
data

输出:

array([[ 1.822   , 74.82825 ],
       [ 3.869   , 70.81949 ],
       ...
       [ 5.287   , 55.585587],
       [ 5.443   , 50.65366 ]], dtype=float32)
n_samples

输出:

190
第二种方式读取
# 第二种方式读取
def read_data(file_name):
    data = pd.read_table('birth_life_2010.txt')
    births = data['Birth rate']
    lifes = data['Life expectancy']
    data = list(zip(births,lifes))
    n_samples = len(data)
    data = np.asarray(data, dtype=np.float32)
    return data,n_samples
data,n_samples=read_data('birth_life_2010.txt')
data,n_samples

输出:

(array([[ 1.822   , 74.82825 ],
        [ 3.869   , 70.81949 ],
        ...
        [ 5.287   , 55.585587],
        [ 5.443   , 50.65366 ]], dtype=float32), 190)

第2步:为输入和标签创建占位符

# tf.placeholder(dtype, shape=None, name=None)
X,Y=None,None
X = tf.placeholder(dtype=tf.float32)
Y = tf.placeholder(dtype=tf.float32)

第3步:创建权重和偏置

# tf.get_variable(name,shape=None,dtype=None,initializer=None,)
# w,b,X,Y都是标量,shape=()可设置为shape=[]
w,b = None,None
w = tf.get_variable(name='weght',shape=(),initializer=tf.zeros_initializer())
b = tf.get_variable(name='bias',shape=(),initializer=tf.zeros_initializer())

第4步:预测

Y_predicted = None
Y_predicted = w * X + b

第5步:指定损失函数

loss = None
loss = tf.square(Y - Y_predicted, name='loss')

第6步:创建优化器

opt = tf.train.GradientDescentOptimizer(learning_rate=0.001)
optimizer = opt.minimize(loss)
import time
start = time.time()

阶段2:训练我们的模型

第7步:初始化及TensorBoard

with tf.Session() as sess:
    # 初始化变量
    sess.run(tf.global_variables_initializer())
    # tensorboard
    writer = tf.summary.FileWriter('./graphs/linear_reg',sess.graph)
    ...

第8步:训练模型100个epochs

with tf.Session() as sess:
    # 初始化变量
    sess.run(tf.global_variables_initializer())
    # tensorboard
    writer = tf.summary.FileWriter('./graphs/linear_reg',sess.graph)
    # trian the model for 100 epoch
    for i in range(100):
        # 初始化每一次的loss
        total_loss=0
        # 每一次,一批批训练
        for x,y in data:
            # 需要运行优化函数optimizer与loss, Tensorflow 会自动更新weight 和bias 两个变量
            _,loss_ = sess.run([optimizer,loss],feed_dict={X:x,Y:y})
            total_loss += loss_
        print('Epoch {0}:{1}'.format(i,total_loss/n_samples))
    writer.close()

输出:

Epoch 0:1661.8637834631543
Epoch 1:956.3224148609137
...
Epoch 98:30.0349335548615
Epoch 99:30.03552558278714

第9步:输出w和b的值

with tf.Session() as sess:
    # 初始化变量
    sess.run(tf.global_variables_initializer())
    # tensorboard
    writer = tf.summary.FileWriter('./graphs/linear_reg',sess.graph)
    # trian the model for 100 epoch
    for i in range(100):
        # 初始化每一次的loss
        total_loss=0
        # 每一次,一批批训练
        for x,y in data:
            # 需要运行优化函数optimizer与loss, Tensorflow 会自动更新weight 和bias 两个变量
            _,loss_ = sess.run([optimizer,loss],feed_dict={X:x,Y:y})
            total_loss += loss_
        print('Epoch {0}:{1}'.format(i,total_loss/n_samples))
    writer.close()
    # 第9步:输出w和b的值
    w_out,b_out = None,None
    w_out, b_out = sess.run([w, b])

输出:

Epoch 0:1661.8637834631543
Epoch 1:956.3224148609137
...
Epoch 98:30.0349335548615
Epoch 99:30.03552558278714

第10步:输出耗时

print('Took: %f seconds' %(time.time() - start))
print('last value of loss, w, b: {0}, {1}, {2}'.format(total_loss/n_samples, w_out, b_out))

输出:

Took: 25.186522 seconds
last value of loss, w, b: 30.03552558278714, -6.07021427154541, 84.92951202392578

第11步:可视化

import matplotlib.pyplot as plt
plt.plot(data[:,0], data[:,1], 'bo', label='Real data')
plt.plot(data[:,0], data[:,0] * w_out + b_out, 'r', label='Predicted data')
plt.legend()

输出

Huber loss

Huber loss是为了增强平方误差损失函数(squared loss function)对噪声(或叫离群点,outliers)的鲁棒性提出的。

对异常值的鲁棒性,如果预测值和实际值之间的差异很小,则将其平方;如果它很大,取其绝对值。

定义:

控制流程

在TensorFlow中,tf.cond()类似于c语言中的if…else…,用来控制数据流向,但是仅仅类似而已,其中差别还是挺大的。

格式:tf.cond(pred, fn1, fn2, name=None)

def huber_loss(label, prediction, delta=14.0):
    residual = tf.abs(label - prediction)
    def f1(): return 0.5*tf.square(residual)
    def f2(): return delta*residual-0.5*tf.square(delta)
    return tf.cond(residual < delta, f1,f2)
# cond函数分为true和false两种情况。在许多情况下,使用函数tf.case。

tf.data

在上面的代码我曾经使用过数据placeholder。但是占位符是一种古老的方式,关于这种方法有各种各样的意见。看来有利于的是,它是一个点,缺点在于它可以很容易地处理数据外的TF较慢处理应被视为一个单独的线程中的数据,和数据瓶颈。因此,这个问题得以解决tf.data。

如何使用tf.data?

tf.data.Dataset.from_tensor_slices((feature, labels))
tf.data.Dataset.from_generator(gen, output_types, output_shapes)

featurelabels必须是Tensor数据类型。但是,由于张量数据类型与numpy数据类型相同,因此可以包含numpy数据类型。

# 换句话说,如果您从上面的模型中读取数据为tf.data,您可以写:
data,n_samples=read_data('birth_life_2010.txt')
dataset = tf.data.Dataset.from_tensor_slices((data[:,0], data[:,1]))
dataset

输出:

<TensorSliceDataset shapes: ((), ()), types: (tf.float32, tf.float32)>
print(dataset.output_types) # >> (tf.float32, tf.float32)
print(dataset.output_shapes) # >> (TensorShape([]), TensorShape([]))
(tf.float32, tf.float32)
(TensorShape([]), TensorShape([]))

tf.data.Dataset有几种方法,你可以直接读取数据文件Tensorflow文件格式分析器。

tf.data.TextLineDataset(filenames) 将文件的每一行读作一个数据。它主要用于读取csv文件和机器翻译领域。

tf.data.FixedLengthRecordData(filenames)它主要用于固定长度数据。数据作为一个数据被接收预定长度。经常使用的地方也经常用于由固定长度组成的数据中。例如,它用于读取诸如CIFAR数据或ImageNet数据之类的内容。

tf.data.TFRecordDataset(filenames)用于tfrecord格式的数据。

我看到了如何读取数据。现在让我们看一下使用数据。在现有代码中,我们for通过语句逐个使用数据的值。tf.data.Iterator使得逐个使用数据变得更加容易。

tf.data.Iterator

iterator = dataset.make_one_shot_iterator()

通过数据集只迭代一次。无需初始化。

iterator = dataset.make_initializable_iterator()

根据需要迭代数据集。需要初始化每个epoch。

iterator = dataset.make_one_shot_iterator()
X, Y = iterator.get_next()
with tf.Session() as sess:
    print(sess.run([X, Y]))        # >> [1.822, 74.82825]
    print(sess.run([X, Y]))        # >> [3.869, 70.81949]
    print(sess.run([X, Y]))        # >> [3.911, 72.15066]
[1.822, 74.82825]
[3.869, 70.81949]
[3.911, 72.15066]

处理TensorFlow中的数据

dataset = dataset.shuffle(1000)
dataset = dataset.repeat(100)
dataset = dataset.batch(128)
dataset = dataset.map(lambda x: tf.one_hot(x, 10)) # convert each elem of dataset to one_hot vector

我们应该使用tf.data?

对于原型设计,feed dict可以更快更容易编写(pythonic)

当您有复杂的预处理或多个数据源时,tf.data很难使用

NLP数据通常只是一个整数序列。在这种情况下,将数据传输到GPU非常快,因此tf.data的加速并不是那么大

优化

使用优化器非常简单。然而只有几行代码可以方便地使用(差分,更新)复杂的配置的优化器。

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss)
_, l = sess.run([optimizer, loss], feed_dict={X: x, Y:y})

会话查看损失所依赖的所有可训练变量并更新它们

tf.Variable(initial_value=None, trainable=True,...)

优化程序会自动计算和更新衍生值。因此,它适用于所有相关变量。在某些情况下,可能存在不应更新的变量。在这种变量的情况下,trainable=False通过仅将其指定为选项,可以很容易地将其设置为不训练

除了上面使用的GD opmizer之外,还提供了各种其他优化器作为张量流函数。以下是优化器列表。

  • tf.train.Optimizer
  • tf.train.GradientDescentOptimizer
  • tf.train.AdadeltaOptimizer
  • tf.train.AdagradOptimizer
  • tf.train.AdagradDAOptimizer
  • tf.train.MomentumOptimizer
  • tf.train.AdamOptimizer
  • tf.train.FtrlOptimizer
  • tf.train.ProximalGradientDescentOptimizer
  • tf.train.ProximalAdagradOptimizer
  • tf.train.RMSPropOptimizer

二、TensorFlow逻辑回归


数据集:MNIST Database

每个图像都是一个28x28阵列,被展平为1-d张量,大小为784

X: 手写数字图像 Y: 数字值

任务:识别图中的数字

模型:Y_predicted = softmax(X * w + b)

损失函数(交叉熵损失): -log(Y_predicted)

1.处理数据

import utils
import tensorflow as tf
import time
learning_rate = 0.01
batch_size = 128
n_epochs = 30
n_train = 60000
n_test = 10000

mnist_folder = 'data/mnist'
utils.download_mnist(mnist_folder) 
train, val, test = utils.read_mnist(mnist_folder, flatten=True)

train_data = tf.data.Dataset.from_tensor_slices(train)
train_data = train_data.shuffle(10000) #
train_data = train_data.batch(batch_size)

test_data = tf.data.Dataset.from_tensor_slices(test)
test_data = test_data.batch(batch_size)

2.创建一个迭代器并确定如何初始化它。

iterator = tf.data.Iterator.from_structure(train_data.output_types,train_data.output_shapes)
img,label = iterator.get_next()
train_init = iterator.make_initializer(train_data)
test_init = iterator.make_initializer(test_data)

3.并生成模型的参数w和b。设置形状以适合img大小。然后,w被初始化为具有均值0和标准差方差0.01的正态分布,并且b被初始化为0。

w = tf.get_variable(name='weight', shape=(784,10), initializer=tf.random_normal_initializer(0,0.01))
b = tf.get_variable(name='bias', shape=(1,10), initializer=tf.zeros_initializer())

4.定义logit和softmax函数并定义损失函数。

logits = tf.matmul(img,w) + b

entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=label, name='entropy')
loss = tf.reduce_mean(entropy, name = 'loss')

5.优化器使用Adam优化器。

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

6.定义预测操作,确认预测是否正确,以及精度计算操作。

preds = tf.nn.softmax(logits)
correct_preds = tf.equal(tf.argmax(preds, 1), tf.argmax(label, 1))
accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))

7.现在让我们可视化及定义session内容。

writer = tf.summary.FileWriter('./graphs/logreg', tf.get_default_graph())

gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.333)
if 'session' in locals() and session is not None:
    print('Close interactive session')
    session.close()
with tf.Session(config=tf.ConfigProto(gpu_options=gpu_options)) as sess:
    start_time = time.time()
    # 初始化变量
    sess.run(tf.global_variables_initializer())
    # 训练
    for i in range(n_epochs):
        sess.run(train_init) # drawing samples from train_data
        total_loss = 0
        n_batches = 0
        try:
            while True:
                _, l = sess.run([optimizer, loss])
                total_loss += l
                n_batches += 1
        except tf.errors.OutOfRangeError:
            pass
        print('Average loss epoch {0}: {1}'.format(i, total_loss/n_batches))
    print('Total time: {0} seconds'.format(time.time() - start_time))

    # test the model
    sess.run(test_init) # drawing samples from test_data
    total_correct_preds = 0
    try:
        while True:
            accuracy_batch = sess.run(accuracy)
            total_correct_preds += accuracy_batch
    except tf.errors.OutOfRangeError:
        pass

    print('Accuracy {0}'.format(total_correct_preds/n_test))
writer.close()

输出:

Average loss epoch 0: 0.3655088067747826
...
Average loss epoch 29: 0.25185961714664173
Total time: 23.884480476379395 seconds
Accuracy 0.917

本文分享自微信公众号 - 光城(guangcity),作者:lightcity

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 开刷Cs20之Tensorflow第二弹

    本节学习来源斯坦福大学cs20课程,有关自学与组队学习笔记,将会放于github仓库与本公众号发布,欢迎大家star与转发,收藏!

    公众号guangcity
  • Tensorboard可视化(一)

    如果可视化不出来,浏览器输入localhost:你的dos下的端口号,进去了没有图片,请检查运行命令,

    公众号guangcity
  • 开刷cs20之Tensorflow第一弹

    本节学习来源斯坦福大学cs20课程,有关自学与组队学习笔记,将会放于github仓库与本公众号发布,欢迎大家star与转发,收藏!

    公众号guangcity
  • Tensorflow | 斯坦福cs20si | lecture1

    上图的代码存在问题,目前不知道怎么修改。若是有朋友有修改方案,请在下方留言,谢谢!

    努力在北京混出人样
  • 人工智能python的tensorflow基础

    IT故事会
  • tensorflow学习笔记_01

    jeremyxu
  • 教程 | 如何基于TensorFlow使用LSTM和CNN实现时序分类任务

    选自burakhimmetoglu 作者:Tom Brander 机器之心编译 参与:蒋思源 时序数据经常出现在很多领域中,如金融、信号处理、语音识别和医药。传...

    机器之心
  • 深度学习(1)——tensorflow简介什么是TensorFlow?什么是数据流图?安装基本概念示例变量的更新操作

    DC童生
  • tf.AUTO_REUSE作用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇
  • Tensorflow可视化编程安装Tensoflow1.0将加法运算以图形化方式展示实现简单的线性回归为程序添加作用域模型的保存与恢复(保存会话资源)

    安装Tensoflow1.0 Linux/ubuntu: python2.7: pip install https://storage.googleapis.c...

    zhaoolee

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动