参考资料:https://www.icourse163.org/learn/PKU-1002536002?tid=1002700003#/learn/announce
https://github.com/cj0012/AI-Practice-Tensorflow-Notes
https://tensorflow.google.cn/
第一次自己写博客,结构可能不太好,慢慢改进,加油!!希望大家批评指正,也希望对大家有帮助,谢谢!!!!
例如:
a = 100
b = "Hello World!"
print"point = %s\n\"%s\""%(a,b)
应打印出:
point = 100
"Hello World!"
c[4:0:-1]
c[4::-1]
c[-2::-2]
从倒数第二个开始一直到头,步长为-2dic = {1:"123","name":"zhangsan","height":180}
dic["name"] = 'zhangsan'
#coding:utf-8
否则出现编码错误= 、<= 、> 、< 、!= 、==
import turtle #导入
t = turtle.Pen() #用turtle模块中的Pen类,实例化出一个叫做t的对象
t.forward(像素点) #让t向前走多少个像素点
t.backward(像素点) #让t向后走多少个像素点
t.left(角度) #让t左转多少角度
t.right(角度) #右转多少角度
t.reset() #让t复位
Ubuntu18.04系统一开始没有安装turtle,需要在终端中输入 sudo apt-get install python-tk
(python3的话,改为python3即可)
def 函数名(参数表):
函数体
例子:
定义:def hi_name(yourname):
print "Hello %s"%yourname
使用:hi_name("zhangsan")
输出: Hello zhangsan
def add(a,b):
return
c = add(5+6) #c被赋值add的返回值11
abs(-10) #返回10
import time
time.asctime()
from PIL import image
t = turtle.Pen()
class 类名(父类名): #父类名只用写一个父类即可,不用写父类的父类等等
pass
class Animals:
def breathe(self):
print "breathe"
def move(self):
print "moving"
class Mammals(Animals):
def breastfeed(self)
print "feeding young"
class Cats(Mammals):
def __init__(self,spots):
self.spots = spots
** __ init __函数,在新对象实例化时会自动运行,用于给新对象赋初值**
例:
kitty = Cats(10) #实例化时默认自动运行__init__函数,给spots赋值,告知kitty有10个斑点
print kitty.spot #打印出10
对象调用类里的函数,用对象.函数名;对象调用类里的变量,用对象.变量名
类内定义函数时,如调用自身或父类的函数与变量,须用self.引导,应写为self.函数名或self.变量名
例:
class Animals:
def breathe(self):
print "breathe"
def move(self):
print "moving"
class Mammals(Animals):
def breastfeed(self)
print "feeding young"
class Cats(Mammals):
def __init__(self,spots):
self.spots = spots
def catch_mouse(self):
print "catch mouse"
def left_foot_forward(self):
print "left foot forward"
def left_foot_backward(self):
print "left foot backward"
def dance(self):
self.left_foot_forward()
self.left_foot_backward()
运行:
kitty = Cat(10) #首先应该实例化
print kitty.spots
kitty.dance() #自己类的函数
kitty.breastfeed() #父类的函数
kitty.move() #父类继承其父类的函数
1. 开:文件变量 = open(“文件路径文件名”,“wb”)
2. 存:pickle.dump(代写入的变量,文件变量)
3. 关:文件变量.close()
例:game_data = {"position":"N2 E3","pocket":["keys","knife"],"money":160}
save_file = open("save.dat","wb") #写入二进制文件
pickle.dump(game_data,save_file)
save_file.close()
例:
load_file = open("save.dat","rb") #读出二进制文件
load_game_data=pickle.load(load_file)
load_file.close()
结果:load_game_data = {"position":"N2 E3","pocket":["keys","knife"],"money":160}
基于TensorFlow的NN:用张量表示数据,用计算图搭建神经网络,用会话执行计算图,优化线上的权重(参数),得到模型。
维数 | 阶 | 名字 | 例子 |
---|---|---|---|
0-D | 0 | 标量scalar | s = 123 |
1-D | 1 | 向量vector | v = [1,2,3] |
2-D | 2 | 矩阵matrix | m = [[1,2,3],[4,5,6],[7,8,9]] |
n-D | n | 张量tensor | t =[[[…]]] n个 |
在命令行中写入:·vim ~/.vimrc
进入编辑界面后写入:set ts = 4
set nu #按Tab键缩进4个字符,并显示行号
例子:import tensorflow as tf
a = tf.constant([1.0,2.0]) #定义张量常数a
b = tf.constant([3.0,4.0]) #定义张量常数b
result = a + b
print result
显示:Tensor(“add:0”,shape=(2,),dtype=float32) 结果是一个张量
add:节点名
0:第0个输出
shape:维度,2行0列
2:2维数组
dtype:数据类型
其只描述了运算过程,没有显示运算结果
import tensorflow as tf
x = tf.constant([[1.0,2.0]]) #定义张量常数x
w = tf.constant([[3.0],[4.0]]) #定义张量常数w
y = tf.matmul(x,w)
print y
####3.1.3 会话(session)####
with tf.Session() as sess:
print sess.run(y) #1.0*3.0+2.0*4.0 = 11.0
显示:[[11.]]
w = tf.Variable(tf.random_normal([2,3],stddev=2,mean=0,seed=1))
tf.zeros([3,2],int32)
生成[[0,0],[0,0],[0,0]]tf.ones([3,2],int32)
生成[[1,1],[1,1],[1,1]]tf.fill([3,2],6)
生成[[6,6],[6,6],[6,6]]tf.constant([3,2,1])
生成[3,2,1]
-变量初始化、计算图节点运算都要用会话(with结构)实现
with tf.Session() as sess:
sess.run()
init_op = tf.global_variables_initializer()
sess.run(init_op)
sess.run(y)
x = tf.placeholder(tf.float32,shape=(1,2))
sess.run(y,feed_dict={x:[[0.5,0.6]]})
x = tf.placeholder(tf.float32,shape=(None,2))
sess.run(y,feed_dict={x:[[0.1,0.2],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
示例代码:
#coding:utf-8
#两层简单的神经网络(全连接)
import tensorflow as tf
#定义输入和参数
x = tf.constant([[0.7,0.5]])
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
#定义前向传播过程
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
#y用会话计算结果
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print "y is:\n",sess.run(y)
结果:[[3.0904665]]
示例代码:
#coding:utf-8
#两层简单的神经网络(全连接)
import tensorflow as tf
#定义输入和参数
#用placeholder实现输入定义(sess.run中喂一组数据)
x = tf.placeholder(tf.float32,shape=(1,2))
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
#定义前向传播过程
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
#y用会话计算结果
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print "y is:\n",sess.run(y,feed_dict={x:[[0.7,0.5]]})
结果:[[3.0904665]]
示例代码:
#coding:utf-8
#两层简单的神经网络(全连接)
import tensorflow as tf
#定义输入和参数
#用placeholder实现输入定义(sess.run中喂一组数据)
x = tf.placeholder(tf.float32,shape=(None,2))
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
#定义前向传播过程
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
#y用会话计算结果
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
print "y is:\n",sess.run(y,feed_dict={x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
print "w1:\n",sess.run(w1)
print "w2:\n",sess.run(w2)
结果:y is:
[[3.0904665]
[1.2236414]
[1.7270732]
[2.2305048]]
w1:
[[-0.8113182 1.4845988 0.06532937]
[-2.4427042 0.0992484 0.5912243 ]]
w2:
[[-0.8113182 ]
[ 1.4845988 ]
[ 0.06532937]]
反向传播:训练模型参数,在所有参数上用梯度下降,使NN模型在训练数据上的损失函数最小
损失函数(loss):预测值(y)与已知答案(y_)的差距
反向传播训练方法: 以减小loss值为优化目标(给出优化器的例子)
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
train_step = tf.train.MomentumOptimizer(learning_rate,momentum).minimize(loss)
train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)
学习率:决定参数每次更新的幅度(初始化为0.001左右)
示例代码:
#coding:uddf-8
#导入模块,生成模拟数据集
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
seed = 23455 #真正编程时不用定义这个
#基于seed产生随机数
rng = np.random.RandomState(seed)
#随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X = rng.rand(32,2)
#从X这个32行2列的矩阵中 取出1行 判断如果和小于1 给Y赋值 如果和不小于1 给Y赋值0
#作为输入数据集的标签(正确答案)
Y = [[int(x0 + x1 <1)] for (x0,x1) in X]
print "X:\n",X
print "Y:\n",Y
#定义神经网络的输入、参数和输出,定义前向传播过程
x = tf.placeholder(tf.float32,shape=(None,2))
y_ = tf.placeholder(tf.float32,shape=(None,1))
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
#定义前向传播过程
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)
#定义损失函数及反向传播方法
loss = tf.reduce_mean(tf.square(y-y_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
#y生成会话,训练STEPS轮
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess_run(init_op)
#输出目前(未经训练)的参数取值
print "w1:\n",sess.run(w1)
print "w2:\n",sess.run(w2)
print "\n"
#训练模型
STEPS = 3000
for i in range(STEPS):
start=(i*BATCH_SIZE)%32
end=start + BATCH_SIZE
sess.run(train_step,feed_dict = {x:X[start:end],y_:Y[start:end]})
if i % 500 == 0
total_loss = sess.run(loss ,feed_dict={x:X,y_:Y})
print("After %d training step(s) , loss on all data is %g" %(i,total_loss))
#输出训练后的参数取值
print "\n"
print "w1:\n",sess.run(w1)
print "w2:\n",sess.run(w2)
搭建神经网络的八股:准备、前传、反传、迭代
with tf.session() as sess
init_op = tf.global_variables_initializer()
sess_run(init_op)
STEPS = 3000
for i in range(STEPS):
start=
end=
sess.run(train_step,feed_dict:)
三种方法:mse(均方误差) (Mean Squared Error)、自定义、ce(交叉熵)(Cross Entropy)
重要问题:学习率设置为多少比较合适?
学习率大了振荡不收敛,学习率笑了收敛速度很慢。
sudo pip install matplotlib
plt.scatter(x坐标,y坐标,c="颜色")
plt.show()
xx,yy = np.mgrid[起:止:步长,起:止:步长]``grid = np.c_[xx.rave(),yy.ravel()] #np.c_组成矩阵,ravel降维拉直
probs = sess.run(y,feed_dict={x:grid})
probs = probs.reshape(xx.shape) #整形,让probs的shape和xx的一样
plt.contour(x轴坐标值,y轴坐标值,该点的高度,levels=[等高线的高度])
plt.show()
示例代码:
#coding:utf-8
#0导入模块 ,生成模拟数据集
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
BATCH_SIZE = 30
seed = 2
#基于seed产生随机数
rdm = np.random.RandomState(seed)
#随机数返回300行2列的矩阵,表示300组坐标点(x0,x1)作为输入数据集
X = rdm.randn(300,2)
#从X这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y赋值1,其余赋值0
#作为输入数据集的标签(正确答案)
Y_ = [int(x0*x0 + x1*x1 <2) for (x0,x1) in X]
#遍历Y中的每个元素,1赋值'red'其余赋值'blue',这样可视化显示时人可以直观区分
Y_c = [['red' if y else 'blue'] for y in Y_]
#对数据集X和标签Y进行shape整理,第一个元素为-1表示,随第二个参数计算得到,第二个元素表示多少列,把X整理为n行2列,把Y整理为n行1列
X = np.vstack(X).reshape(-1,2)
Y_ = np.vstack(Y_).reshape(-1,1)
print X
print Y_
print Y_c
#用plt.scatter画出数据集X各行中第0列元素和第1列元素的点即各行的(x0,x1),用各行Y_c对应的值表示颜色(c是color的缩写)
plt.scatter(X[:,0], X[:,1], c=np.squeeze(Y_c))
plt.show()
#定义神经网络的输入、参数和输出,定义前向传播过程
def get_weight(shape, regularizer):
w=tf.Variable(tf.random_normal(shape), dtype=tf.float32)
tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
return w
def get_bias(shape):
b = tf.Variable(tf.constant(0.01, shape=shape))
return b
x = tf.placeholder(tf.float32, shape=(None, 2))
y_ = tf.placeholder(tf.float32, shape=(None, 1))
w1 = get_weight([2,11], 0.01)
b1 = get_bias([11])
y1 = tf.nn.relu(tf.matmul(x, w1)+b1)
w2 = get_weight([11,1], 0.01)
b2 = get_bias([1])
y = tf.matmul(y1, w2)+b2
#定义损失函数
loss_mse = tf.reduce_mean(tf.square(y-y_))
loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))
#定义反向传播方法:不含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_mse)
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
STEPS = 40000
for i in range(STEPS):
start = (i*BATCH_SIZE) % 300
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x:X [start:end], y_:Y_[start:end]})
if i % 2000 == 0:
loss_mse_v = sess.run(loss_mse, feed_dict={x:X, y_:Y_})
print("After %d steps, loss is: %f" %(i, loss_mse_v))
#xx在-3到3之间以步长为0.01,yy在-3到3之间以步长0.01,生成二维网格坐标点
xx, yy = np.mgrid[-3:3:.01, -3:3:.01]
#将xx , yy拉直,并合并成一个2列的矩阵,得到一个网格坐标点的集合
grid = np.c_[xx.ravel(), yy.ravel()]
#将网格坐标点喂入神经网络 ,probs为输出
probs = sess.run(y, feed_dict={x:grid})
#probs的shape调整成xx的样子
probs = probs.reshape(xx.shape)
print "w1:\n",sess.run(w1)
print "b1:\n",sess.run(b1)
print "w2:\n",sess.run(w2)
print "b2:\n",sess.run(b2)
plt.scatter(X[:,0], X[:,1], c=np.squeeze(Y_c))
plt.contour(xx, yy, probs, levels=[.5])
plt.show()
#定义反向传播方法:包含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_total)
with tf.Session() as sess:
init_op = tf.global_variables_initializer()
sess.run(init_op)
STEPS = 40000
for i in range(STEPS):
start = (i*BATCH_SIZE) % 300
end = start + BATCH_SIZE
sess.run(train_step, feed_dict={x: X[start:end], y_:Y_[start:end]})
if i % 2000 == 0:
loss_v = sess.run(loss_total, feed_dict={x:X,y_:Y_})
print("After %d steps, loss is: %f" %(i, loss_v))
xx, yy = np.mgrid[-3:3:.01, -3:3:.01]
grid = np.c_[xx.ravel(), yy.ravel()]
probs = sess.run(y, feed_dict={x:grid})
probs = probs.reshape(xx.shape)
print "w1:\n",sess.run(w1)
print "b1:\n",sess.run(b1)
print "w2:\n",sess.run(w2)
print "b2:\n",sess.run(b2)
plt.scatter(X[:,0], X[:,1], c=np.squeeze(Y_c))
plt.contour(xx, yy, probs, levels=[.5])
plt.show()
模块化搭建思想(多个py文件,方便扩展)
全连接NN:每个神经元与前后相邻层的每一个神经元都有链接关系,输入时特征,输出为预测的结果。
参数个数为:前层*后层+后层
提供6W张28*28像素点的0-9手写数字图片和标签,用于训练。
提供1W张28*28像素点的0-9手写数字图片和标签,用于测试。
每张图片的784个像素点组成长度为783的一维数组,作为输入特征。
图片的标签以一位数组的形式给出,每个元素表示对应分类出现的概率。
有用的函数
tf.get_collection("") #从集合中取全部变量,生成一个列表
tf.add_n([]) #列表内对应元素相加
tf.cast(x,dtype) #把x转化为dtpye类型
tf.argmax(x,axis) #返回最大值所在索引号 如:tf.argmax([1,0,0],1)sve返回0
os.path.join("home","name") #返回home/name这种路径的形式
字符串.split() #按指定拆分符对字符串切片,返回分隔后的列表,这个可以从一个路径名中截取一个文件名,例:'./model/mnist_model-1001'.split('/')[-1].split('-')[-1] 返回1001
with tf.Graph().as_default() as g: #其内定义的节点在计算图g
保存模型
saver = tf.train.Saver() #实例化saver对象
with tf.Session() as sess: #在with结构for循环中一定轮数时保存模型到当前会话
for i in range(STEPS):
if i % 轮数 == 0:
saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step = global_step)
加载模型
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(存储路径)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess,ckpt.model_checkpoint_path)
加入代码:
ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH)
if ckpt and ckpt.model_checkpoint_path:
saver.restore(sess, ckpt.model_checkpoint_path)
实现关闭中断后,再次运行,是从上一次的节点处运行,不需要再从头训练了。
使用tfrecords文件
tfrecords是一种二进制文件,可先将图片和标签制作成该格式的文件。使用tfrecoreds进行数据读取,会提高内存利用率。
用 tf.train.Example的协议存储训练数据。训练数据的特征用键值对的形式表示。
如:‘img_raw’:值 ‘label’:值 值是Byteslist/FloatList/int64List
用SerializeToString()把数据序列化成字符串存储。
生成tfrecords文件(见代码)
解析tfrecprds文件(见代码)
例如:单通道的灰度图片
tf.nn.conv2d(输入描述,eg.[batch,5,5,1]) #batch是一次喂入图片的个数,(5,5)为分辨率,1为通道数(灰度图为1,彩色图为3)
卷积核描述,eg.[3,3,1,16] #(3,3)为行列分辨率,1为通道数(由输入图片的通道数决定),16为核个数(即输出图片的深度为16(输出为16通道))
核滑动步长,eg.[1,1,1,1] #第二个‘1’为行步长和第三个‘1’为列步长,第一个和第四个参数都固定是1
padding = 'VALID' #不使用padding填充)
格式:
tf.nn.conv2d(输入描述,eg.[batch,5,5,3]) #batch是一次喂入图片的个数,(5,5)为分辨率,3为通道数(灰度图为1,彩色图为3)
卷积核描述,eg.[3,3,1,16] #(3,3)为行列分辨率,1为通道数(由输入图片的通道数决定),16为核个数(即输出图片的深度为16(输出为16通道))
核滑动步长,eg.[1,1,1,1] #第二个‘1’为行步长和第三个‘1’为列步长,第一个和第四个参数都固定是1
padding = 'SAME' #使用padding填充)
pool = tf.nn.max_pool(输入描述,eg.[batch,28,28,6]) #batch是一次喂入图片的个数,(28,28)为分辨率,6为通道数
池化核描述(仅大小),eg.[1,2,2,1] #(2,2)为行列分辨率,第一个和第四个参数都固定是1
池化核滑动步长,eg.[1,2,2,1] #第二个‘2’为行步长和第三个‘2’为列步长,第一个和第四个参数都固定是1
padding = 'SAME'
if train: 输出 = tf.nn.dropout(上层输出,暂时舍弃的概率)
[ 5 * 5 * 16]即为卷积神经网络提取的特征,将其作为输入喂给全连接网络。
x = tf.placeholder(tf.float32,shape = [BATCH,IMAGE_PIXELS]) #shape = [1,224,224,3] 1:表示一次喂入一个图片;224,224,3是图片的分辨率和通道数
tf.placeholder用于传入真实的训练样本、测试、真实特征、待处理特征,仅占位,不必给初值,用sess.run的feed_dict参数以字典的形式喂入x:sess.run(求分类评估值的节点,feed_dict{x: })
np.load/save将数组以二进制格式 读出/写入磁盘,扩展名为.npy。
np.save("名.npy",某数组)
某变量 = np.load("名.mpy",encoding = '').item() #.item()为遍历(键值对)
如:
data_dict = np.load(vgg.npy,encoding = 'latin1').item() #读vgg16.npy文件,遍历其内键值对,导出模型参数赋给data_dict
tf.nn.bias_add(乘加和,bias)
把bias加到乘加和上
tf.reshape(tensor,[n行,n列])(将张量变为需要的维度)
[-1,m列]:-1表示行跟随m列自动调整
np.argsort(列表)
对列表从小到大排序,返回索引值
os.getcwd()
返回当前的工作目录
os.path.join( , ,…)
拼接出整个文件路径,可引导到特定的文件
例子:
vgg16_path = os.path.join(os.getcwd(),"vgg16.npy") #当前目录为/vgg16.npy 索引到文件vgg16.npy
tf.split(切谁,怎么切,在哪个维度切)
例如:value是一个[5,30]的张量。
split0,split1,split2 = tf.split(value,[4,5,11],1)
输出:tf.shape(split0) ==>[5,4];
tf.shape(split1) ==>[5,5];
tf.shape(split2) ==>[5,11];
再如:value是一个[5,30]的张量。
split0,split1,split2 = tf.split(value,num_or_size_splits=3,axis = 1) #均分
输出:tf.shape(split0) ==>[5,10];
tf.shape(split1) ==>[5,10;
tf.shape(split2) ==>[5,10];
fig = plt.figure(“图名字”) #实例化图对象
img = io.imread(图片路径) #读入图片
ax = fig.add_subplot(数,数,数) #数数数分别是:包含几行、包含几列、当前是第几个
ax.bar(bar的个数,bar的值,每个bar的名字,bar宽,bar色)
ax.set_ylabel(" ") #y轴名字 ,如果使用中文,应该这样子使用:u“中文”
ax.set_title("") #子图名字
ax.text(文字x坐标,文字y坐标,ha = 'center',va = 'bottom',fontsize = 7)
ax = imshow(图) 画子图
print self.data_dict
看一下具体的参数。全部代码见我github:https://github.com/yyysjz1997/Introduction-to-Artificial-Intelligence
我的github中有更多的好玩的小东西哦!
https://github.com/yyysjz1997