tensorflow框架(一)

学习mooc人工智能实践:tensorflow笔记的笔记

基于tensorflow搭建NN的路径:用张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上权重(参数),得到模型。

用ubuntu中anaconda装tensorflow
用source activate tf 激活环境
退出环境 source deactivate

对于一些不能编译的warning,可以屏蔽

vim ~/.bashrc

在最后一行加入

`export TF_CPP_MIN_LOG_LEVEL=2

降低tensorflow的提示等级
再在终端运行

source ~/.bashrc

使刚才的配置文件生效

张量(tensor)

在这里插入图片描述

数据类型:

tf.float32 , tf.int32,
tf.bool: tf.constant([True,False])
tf.string: tf.constant(“Hello, World!”)

创建张量

tf.constant(张量内容,dtype=数据类型)
全为0:tf.zeros(维度)
全为1:tf.ones(维度)
全为指定值:tf.fill(维度,指定值)
生成正态分布随机数:tf.random.normal(维度,mean=均值,stddev=标准差)
生成截断式正态分布随机数:tf.random.truncated_normal(维度,mean=均值,stddev=标准差)如果生成的数据,偏离当前均值两个标准差,将重新生成
生成均匀分布随机数:tf.random.uniform(维度,minval=最小值,maxval=最大值)

维度:
一维 直接写个数
二维 用 [行,列]
多维 用 [n,m,j,k,…]

查看类型:tensor.dtype
查看形状: tensor.shape
将numpy数据类型转换为Tensor数据类型:
tf.convert_to_tensor(数据名,dtype=数据类型)

常用函数

强制tensor类型转换

tf.cast(张量名,dtype = 数据类型)

计算张量维度上的最小元素

tf.reduce_min(张量名)

计算张量维度上的最大元素

tf.reduce_max(张量名)

axis指定操作的方向

axis=0表示纵向,跨行
axis=1表示横向,跨列
不指定axis,所有元素参与运算

返回某维度上最大值的索引号

tf.argmax(张量名,axis=操作轴)

计算张量沿着指定维度的平均值

tf.reduce_mean(张量名,axis=操作轴)

计算张量沿着指定维度的和

tf.reduce_sum(张量名,axis=操作轴)

tf.Variable()将变量标记为可训练

tf.Variable(初始值)将变量标记为可训练,被标记的变量会在反向传播中记录梯度信息。神经网络训练中,常用该函数标记待训练参数

数学运算

加减乘除:tf.add(张量1,张量2),tf.subtract(张量1,张量2),tf.multipy(张量1,张量2),tf.divide(张量1,张量2)
平方、次方与开方:tf.square(张量名),tf.pow(张量名,n次方数),tf.sqrt(张量名)
矩阵乘法:tf.matmul(矩阵1,矩阵2)

特征和标签配对

适用numpy格式和tensor格式
切分传入张量的第一维度,生成输入特征标签对,构建数据集
tf.data.Dataset.from_tensor_slices((输入特征,标签))

求张量梯度

with结构记录计算过程,gradient求出张量的梯度

with tf.GradientTape() as tape:
    若干个计算过程
grad = tape.gradient(函数,对谁求导)
print(grad)

遍历每个元素

enumerate是python的内建函数,它可遍历每个元素(如列表,元组或字符串),组合为:索引,元素,常在for循环中使用。

seq = ['one', 'two', 'three']
for i,element in enumerate(seq)
    print(i, element)

独热编码

tf.one_hot(带转换数据,depth=几分类)

Softmax

在这里插入图片描述
n分类的n个输出(y0,y1,…,yn-1)通过softmax()函数,便符合概率分布了

自更新,自减

调用assign_sub前,先用tf.Variable定义变量w为可训练(可自更新)
w.assign_sub(w要自减的内容)

tf.where()

tf.where(条件语句,真返回A,假返回B)

生成随机数

np.random.RandomState.rand(维度,seed= )

两个数组按垂直方向叠加

np.vstack(数组1,数组2)

生成网格坐标点

np.mgrid[起始值:结束值:步长,起始值:结束值:步长,...]
x.ravel()将x变成一维数组
np.c_[数组1,数组2,...]使返回的间隔数值点配对
在这里插入图片描述

鸢尾花分类

from sklearn import datasets
from pandas import DataFrame
import pandas as pd

x_data = datasets.load_iris().data  # .data返回iris数据集所有输入特征
y_data = datasets.load_iris().target  # .target返回iris数据集所有标签
print("x_data from datasets: \n", x_data)
print("y_data from datasets: \n", y_data)

x_data = DataFrame(x_data, columns=['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度']) # 为表格增加行索引(左侧)和列标签(上方)
pd.set_option('display.unicode.east_asian_width', True)  # 设置列名对齐
print("x_data add index: \n", x_data)


x_data['类别'] = y_data  # 新加一列,列标签为‘类别’,数据为y_data
print("x_data add a column: \n", x_data)

#类型维度不确定时,建议用print函数打印出来确认效果

在这里插入图片描述

# -*- coding: UTF-8 -*-
# 利用鸢尾花数据集,实现前向传播、反向传播,可视化loss曲线

# 导入所需模块
import tensorflow as tf
from sklearn import datasets
from matplotlib import pyplot as plt
import numpy as np

# 导入数据,分别为输入特征和标签
x_data = datasets.load_iris().data
y_data = datasets.load_iris().target

# 随机打乱数据(因为原始数据是顺序的,顺序不打乱会影响准确率)
# seed: 随机数种子,是一个整数,当设置之后,每次生成的随机数都一样(为方便教学,以保每位同学结果一致)
np.random.seed(116)  # 使用相同的seed,保证输入特征和标签一一对应
np.random.shuffle(x_data)
np.random.seed(116)
np.random.shuffle(y_data)
tf.random.set_seed(116)

# 将打乱后的数据集分割为训练集和测试集,训练集为前120行,测试集为后30行
x_train = x_data[:-30]
y_train = y_data[:-30]
x_test = x_data[-30:]
y_test = y_data[-30:]

# 转换x的数据类型,否则后面矩阵相乘时会因数据类型不一致报错
x_train = tf.cast(x_train, tf.float32)
x_test = tf.cast(x_test, tf.float32)

# from_tensor_slices函数使输入特征和标签值一一对应。(把数据集分批次,每个批次batch组数据)
train_db = tf.data.Dataset.from_tensor_slices((x_train, y_train)).batch(32)
test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)

# 生成神经网络的参数,4个输入特征,故输入层为4个输入节点;3分类,故输出层为3个神经元
# 用tf.Variable()标记参数可训练
# 使用seed使每次生成的随机数相同(方便教学,使大家结果都一致,在现实使用时不写seed)
w1 = tf.Variable(tf.random.truncated_normal([4, 3], stddev=0.1, seed=1))
b1 = tf.Variable(tf.random.truncated_normal([3], stddev=0.1, seed=1))

lr = 0.1  # 学习率为0.1
train_loss_results = []  # 将每轮的loss记录在此列表中,为后续画loss曲线提供数据
test_acc = []  # 将每轮的acc记录在此列表中,为后续画acc曲线提供数据
epoch = 500  # 循环500轮
loss_all = 0  # 每轮分4个step,loss_all记录四个step生成的4个loss的和

# 训练部分
for epoch in range(epoch):  #数据集级别的循环,每个epoch循环一次数据集
    for step, (x_train, y_train) in enumerate(train_db):  #batch级别的循环 ,每个step循环一个batch
        with tf.GradientTape() as tape:  # with结构记录梯度信息
            y = tf.matmul(x_train, w1) + b1  # 神经网络乘加运算
            y = tf.nn.softmax(y)  # 使输出y符合概率分布(此操作后与独热码同量级,可相减求loss)
            y_ = tf.one_hot(y_train, depth=3)  # 将标签值转换为独热码格式,方便计算loss和accuracy
            loss = tf.reduce_mean(tf.square(y_ - y))  # 采用均方误差损失函数mse = mean(sum(y-out)^2)
            loss_all += loss.numpy()  # 将每个step计算出的loss累加,为后续求loss平均值提供数据,这样计算的loss更准确
        # 计算loss对各个参数的梯度
        grads = tape.gradient(loss, [w1, b1])

        # 实现梯度更新 w1 = w1 - lr * w1_grad    b = b - lr * b_grad
        w1.assign_sub(lr * grads[0])  # 参数w1自更新
        b1.assign_sub(lr * grads[1])  # 参数b自更新

    # 每个epoch,打印loss信息
    print("Epoch {}, loss: {}".format(epoch, loss_all/4))
    train_loss_results.append(loss_all / 4)  # 将4个step的loss求平均记录在此变量中
    loss_all = 0  # loss_all归零,为记录下一个epoch的loss做准备

    # 测试部分,并计算acc
    # total_correct为预测对的样本个数, total_number为测试的总样本数,将这两个变量都初始化为0
    total_correct, total_number = 0, 0
    for x_test, y_test in test_db:
        # 使用更新后的参数进行预测
        y = tf.matmul(x_test, w1) + b1
        y = tf.nn.softmax(y)
        pred = tf.argmax(y, axis=1)  # 返回y中最大值的索引,即预测的分类
        # 将pred转换为y_test的数据类型
        pred = tf.cast(pred, dtype=y_test.dtype)
        # 若分类正确,则correct=1,否则为0,将bool型的结果转换为int型
        correct = tf.cast(tf.equal(pred, y_test), dtype=tf.int32)
        # 将每个batch的correct数加起来
        correct = tf.reduce_sum(correct)
        # 将所有batch中的correct数加起来
        total_correct += int(correct)
        # total_number为测试的总样本数,也就是x_test的行数,shape[0]返回变量的行数
        total_number += x_test.shape[0]
    # 总的准确率等于total_correct/total_number
    acc = total_correct / total_number
    test_acc.append(acc)
    print("Test_acc:", acc)
    print("--------------------------")

# 绘制 loss 曲线
plt.title('Loss Function Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Loss')  # y轴变量名称
plt.plot(train_loss_results, label="$Loss$")  # 逐点画出trian_loss_results值并连线,连线图标是Loss
plt.legend()  # 画出曲线图标
plt.show()  # 画出图像

# 绘制 Accuracy 曲线
plt.title('Acc Curve')  # 图片标题
plt.xlabel('Epoch')  # x轴变量名称
plt.ylabel('Acc')  # y轴变量名称
plt.plot(test_acc, label="$Accuracy$")  # 逐点画出test_acc值并连线,连线图标是Accuracy
plt.legend()
plt.show()

神经网络优化

复杂度

空间复杂度=层数(隐藏层+输出层)+参数个数(总w+总b)
时间复杂度=乘加运算次数

学习率

在这里插入图片描述
在这里插入图片描述

激活函数

在这里插入图片描述
在这里插入图片描述

sigmoid在这里插入图片描述

深层神经网络的求梯度需要多层链式求导,也就是多个0-0.25的数相乘,最终会趋于0,造成梯度消失,参数无法继续更新

我们希望输入每层神经网络的特征都是以0为均值的小数值,sigmoid的都是正数,会使收敛变慢

Tanh函数

在这里插入图片描述

Relu函数

在这里插入图片描述

Leaky Relu函数

在这里插入图片描述

建议

在这里插入图片描述

损失函数

均方误差MSE

loss_mse=tf.reduce_mean(tf.squre(y_-y))

自定义

在这里插入图片描述

交叉熵cross entropy

在这里插入图片描述
tf.losses.categorical_crossentropy(y_, y)
分类问题可以用softmax函数与交叉熵结合,输出先过softmax函数,再计算y与y_的交叉熵损失函数
tf.nn.softmax_cross_entropy_with_logits(y_, y)

缓解过拟合

欠拟合的解决办法:
1.增加输入特征项
2.增加网络参数
3.减少正则化参数

过拟合的解决办法:
1.数据清洗
2.增大训练集
3.采用正则化
4.增大正则化参数

正则化

在这里插入图片描述
在这里插入图片描述

神经网络参数优化器

在这里插入图片描述
不同的优化器,实际上只是定义了一阶动量和二阶动量的函数

随机梯度下降SGD

没有动量
在这里插入图片描述

SGDM

引入一阶动量
在这里插入图片描述
mt表示各时刻梯度方向的指数滑动平均,0时刻为0

Adagrad

在SGD基础上,引入二阶动量,可以对模型中的每一个参数分配自适应学习率了
在这里插入图片描述

RMSProp

在SGD基础上增加二阶动量
在这里插入图片描述

Adam

同时结合SGDM一阶动量和RMSProp二阶动量
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值