4 months ago

一、建立模型

以经典的minist数据集中的手写数字识别为例
每张照片图片均是高为28,宽为28的二维张量(因为是黑白照片,深度为1,这里不考虑深度)
我们在这里建立一个这样的神经网络结构:输入层为 28*28=784个神经元,一层隐藏层200个神经元,输出层10个神经元

import tensorflow as tf

# 1.构建全连接神经网络
def full_connect_neural_network(data):
        # 定义网络结构:输入层、隐藏层、输出层
    input,hid,output=784,200,10
    # 第一层(隐藏层)的权重矩阵和偏置(采用正态分布进行随机初始化)
    w1=tf.random_normal([input,hid],mean=0,stddev=1)
    b1=tf.random_normal([hid],0,1)
    # 隐藏层的结果,采用sigmoid激活函数
    l1=tf.matmul(data,w1)+b1
    h1=tf.nn.sigmoid(l1)
    # 第二层(输出层)的权重矩阵和偏置
    w2=tf.random_normal([hid,output],0,1)
    b2=tf.random_normal([output],0,1)
    # 输出层的结果(这里不能使用激活函数,后续进行交叉熵运算的时候会自动运行激活函数)
    l2=tf.matmul(h1,w2)+b2
    
    return l2
    
# 2.读取图片,数据处理后作为神经网络的输入值
# 读取图片文件
img=tf.read_file("./data/0/1_0.jpg","r")
# 将图片解码为tensor
img=tf.image.decode_jpeg(img)
# 将图片张量形状转换为一行(二维的)
img=tf.reshape(img,[1,-1])
# 数据归一化
img=img/255
# 数据类型转换(uint8转换成float32)
img=tf.cast(img,tf.float32)

# 3.调用神经网络
output=full_connect_neural_network(img)
sess=tf.Session()
print(sess.run(output))

因为初始值是随机生成的,所以每次运算结果差别很大

以上过程,是我们在只有特征值的情况下利用全连接神经网络实现分类结果预测
但是这个预测结果的准确性无从验证
接下来我们引入损失函数来判断预测结果的准确性

二、损失函数

对于多分类问题的损失函数,通常采用sigmoid交叉熵和softmax交叉熵
1.sigmoid交叉熵损失函数
测量每个类别独立且不相互排斥的离散分类任务中的概率。(可以执行多标签分类,其中图片可以同时包含大象和狗)


tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None,name=None)

其中lables表示真实值,logits表示预测值(字面意思为统计值,任正非刚刚说过:人工智能就是统计学+计算机)
_sentinel:该参数为内部使用,实际运用中不会使用。
目的是占据函数参数的第一个位置,让我们不能通过位置传递labels 和 logits,而是使用关键字传递参数,避免混淆。
原理是:实际使用时_sentinel不用传入该参数,所以我们想要通过位置传递 labels 和 logits 时,实际上参数传递情况为传给了 _sentinel, labels。函数内部检查 logits没有值传进来,就会报错。

该API会先进行一次softmax运算,然后计算交叉熵,因此输入的预测值无需提前进行softmax运算。

接着上面的例子,代码写下去就是

# 输入的图片标签为“0”,首先进行one-hot编码
labels=tf.one_hot([0],depth=10)
# 获取预测值
logits=sess.run(output)
entropy=tf.nn.sigmoid_cross_entropy_with_logits(labels=labels,logits=logits)
# 此时的交叉熵是一个一行十列的二维张量,为便于观察、计算,需要转换成一个常量
loss=tf.reduce_sum(entropy)

2.softmax交叉熵损失函数
测量类别相互排斥的离散分类任务中的概率(每个条目恰好在一个类别中)
(有一个且只有一个标签:图像可以是狗或卡车,但不能同时为两个)



tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)
注意: 每行labels[i]必须是有效的概率分布。如果不是,梯度的计算将是不正确的。
警告:此操作期望未缩放的logits,因为它softmax 在logits内部执行效率。
该API会先进行一次softmax运算,然后计算交叉熵,因此输入的预测值无需提前进行softmax运算。
lables的数据必须经过One-Hot Encoding

接着上面的例子,代码写下去就是

# 输入的图片标签为“0”,首先进行one-hot编码
labels=tf.one_hot([0],depth=10)
# 获取预测值
logits=sess.run(output)
entropy=tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits)
# 此时的交叉熵是一个一行十列的二维张量,为便于观察、计算,需要转换成一个常量
loss=tf.reduce_sum(entropy)

三、采用梯度下降法识别单张图片(完整代码)

import tensorflow as tf

# 1.构建全连接神经网络
def full_connect_neural_network(data):
    input,hid,output=784,200,10
    # 第一层的权重矩阵和偏置(设置为变量,后期需要多次训练)
    w1=tf.Variable(tf.random_normal([input,hid],mean=0,stddev=1))
    b1=tf.Variable(tf.random_normal([hid],0,1))
    # 隐含层的结果,采用sigmoid激活函数
    l1=tf.matmul(data,w1)+b1
    h1=tf.nn.sigmoid(l1)
    # 第二层的权重矩阵和偏置(设置为变量,后期需要多次训练)
    w2=tf.Variable(tf.random_normal([hid,output],0,1))
    b2=tf.Variable(tf.random_normal([output],0,1))
    # 输出层的结果(这里不能使用激活函数,后续进行交叉熵运算的时候会自动运行激活函数)
    l2=tf.matmul(h1,w2)+b2
    
    return l2

# 2.读取图片,数据处理后作为神经网络的输入值
# 读取图片文件
img=tf.read_file("./data/0/1_0.jpg","r")
# 将图片解码为tensor
img=tf.image.decode_jpeg(img)
# 将图片张量形状转换为一行(二维的)
img=tf.reshape(img,[1,-1])
# 数据归一化
img=img/255
# 数据类型转换(uint8转换成float32)
img=tf.cast(img,tf.float32)

# 3.调用神经网络
# 获取真实值:输入的图片标签为“0”,首先进行one-hot编码
labels=tf.one_hot([0],depth=10)
# 获取预测值
logits=full_connect_neural_network(img)
# 计算损失函数:这里以softmax交叉熵损失函数为例
entropy=tf.nn.softmax_cross_entropy_with_logits(labels=labels,logits=logits)
# 此时的交叉熵是一个一行十列的二维张量,为便于观察、计算,需要转换成一个常量
loss=tf.reduce_sum(entropy)
# 定义训练方法:基本梯度下降大法
opti=tf.train.GradientDescentOptimizer(0.01).minimize(loss)

# 4.创建会话,开始训练
sess=tf.Session()
loss_map=[]
sess.run(tf.global_variables_initializer())
for i in range(30):
    sess.run(opti,{labels:sess.run(labels),logits:sess.run(logits)})
        # 收集每次训练后的损失值,观察训练过程是否达到预期效果
    loss_map.append(sess.run(loss,{labels:sess.run(labels),logits:sess.run(logits)}))
    # 获取每次的预测值
    predict=sess.run(tf.arg_max(sess.run(logits),1)) #获取最大值的下标,这里代表预测结果
    print("第%d次迭代的预测结果为:" %i ,predict)
print(loss_map)

四、采用梯度下降法识别多张图片(完整代码)

五、全连接神经网络的缺陷----自变量个数太多

全连接神经网络的自变量个数计算原理展示如下


我们这里使用的神经网络结构:输入层为 28*28=784个神经元,一层隐藏层200个神经元,输出层10个神经元
从输入层到隐藏层的自变量个数:784*200+200=157000
从隐藏层到输出层的自变量个数:200*10+10=2010
因此总的自变量个数为:157000+2010=159010
这只是一个最简单的两层神经网络而已,如果增加网络层数和每一次的神经元个数,那么自变量总数会很多
在利用梯度下降法时,需要计算每个自变量的偏导数,这个计算量和复杂度非常大

神经网络的梯度反向传播算法(常称为BP算法)巧妙地解决了该问题,后续进行研究

参考资料:
张平:《图解深度学习与神经网络》
tensorflow 分类函数(交叉熵的计算)
任正非:人工智能就是统计学,我们国家对统计学重视不够
tf.nn.softmax_cross_entropy_with_logits

 
4 months ago

1.one-hot编码背景知识

独热编码一般是在有监督学习中对数据集进行标注时候使用的
指的是在分类问题中,将存在数据类别的那一类用X表示,不存在的用Y表示,这里的X常常是1, Y常常是0。

2.tensorflow接口

one_hot(
    indices, #输入,这里是一维的
    depth, #one hot dimension.
    on_value=None, #output 默认1
    off_value=None, #output 默认0
    axis=None, #0表示列,1表示行,默认为1
    dtype=None,#默认为tf.float32
    name=None
)

3.示例

w=tf.one_hot([0,1,2,3,4,5],depth=10)
sess=tf.Session()
sess.run(w)

运行结果为:

array([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.]], dtype=float32)
 
4 months ago

1.问题描述

假设xyz三维空间中有六个点:(1,1,8),(2,1,12),(3,2,10),(1,2,14),(4,5,28),(5,8,10)
寻找一个超平面 z = f(x,y) =(w1*x + w2*y + b)** 2
使得这些点到超平面(沿z轴方向)的距离和(即损失函数)最小

2.代码实现

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# tf.placeholder用于传入训练数据    
xy=tf.placeholder(tf.float32,[None,2])
z_true=tf.placeholder(tf.float32,[None,1])
# tf.Variable用于定义需要最终得到的系数(训练过程中,这些系数处于不断变化中)
w=tf.Variable([[1.0],[1.0]],tf.float32)
b=tf.Variable([1.0],tf.float32)
# 构建目标函数
z_predict=tf.pow(tf.matmul(xy,w)+b,2.0)
# 构建损失函数
loss=tf.reduce_sum(tf.square(z_true-z_predict))
# 使用梯度下降进行训练
optimer=tf.train.GradientDescentOptimizer(0.005).minimize(loss)
# 准备训练数据
xy_train=np.array([[1,1],[2,1],[3,2],[1,2],[4,5],[5,8]],np.float32)
z_true_train=np.array([[8],[12],[10],[14],[28],[10]],np.float32)
# 创建会话
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    loss_map=[]
    for i in range(500):
        sess.run(optimer,{xy:xy_train,z_true:z_true_train})
        loss_map.append(sess.run(loss,{xy:xy_train,z_true:z_true_train}))
        if i%50==0:
            print("第%d次迭代产生的w1,w2,b分别是:" %i,sess.run([w,b]))
    print("第500次迭代产生的w1,w2,b分别是:",sess.run([w,b]))
plt.plot([i+1 for i in range(len(loss_map))],loss_map)
plt.show()

3.小结

整个过程跟线性回归并没有什么不同,只是目标函数不同而已
但是这个案例一上来就遇到了梯度爆炸问题,不知道是数据集还是训练方法的问题,此处存疑

一周后更新:
梯度爆炸主要是训练方法的问题,放弃传统的梯度下降方法,使用梯度下降改进算法
比如简单尝试tf.train.AdagradOptimizer(0.25,0.01).minimize(loss)后,整个过程就很顺利

 
4 months ago

1.问题描述

假设xyz三维空间中有六个点:(1,1,8),(2,1,12),(3,2,10),(1,2,14),(4,5,28),(5,8,10)
寻找一个超平面 z = f(x,y) = w1*x + w2*y + b
使得这些点到超平面(沿z轴方向)的距离和(即损失函数)最小

2.代码实现

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# tf.placeholder用于传入训练数据    
xy=tf.placeholder(tf.float32,[None,2])
z_true=tf.placeholder(tf.float32,[None,1])
# tf.Variable用于定义需要最终得到的系数(训练过程中,这些系数处于不断变化中)
w=tf.Variable([[1.0],[1.0]],tf.float32)
b=tf.Variable([1.0],tf.float32)
# 构建目标函数
z_predict=tf.matmul(xy,w)+b
# 构建损失函数
loss=tf.reduce_sum(tf.square(z_true-z_predict))
# 使用梯度下降进行训练
optimer=tf.train.GradientDescentOptimizer(0.005).minimize(loss)
# 准备训练数据
xy_train=np.array([[1,1],[2,1],[3,2],[1,2],[4,5],[5,8]],np.float32)
z_true_train=np.array([[8],[12],[10],[14],[28],[10]],np.float32)
# 创建会话
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    loss_map=[]
    for i in range(500):
        sess.run(optimer,{xy:xy_train,z_true:z_true_train})
        loss_map.append(sess.run(loss,{xy:xy_train,z_true:z_true_train}))
        if i%50==0:
            print("第%d次迭代产生的w1,w2,b分别是:" %i,sess.run([w,b]))
    print("第500次迭代产生的w1,w2,b分别是:",sess.run([w,b]))
plt.plot([i+1 for i in range(len(loss_map))],loss_map)
plt.show()

运行结果如下:

第0次迭代产生的w1,w2,b分别是: [array([[1.95],
       [1.99]], dtype=float32), array([1.41], dtype=float32)]
第50次迭代产生的w1,w2,b分别是: [array([[ 3.3900864],
       [-0.6532512]], dtype=float32), array([5.929905], dtype=float32)]
第100次迭代产生的w1,w2,b分别是: [array([[ 2.9388034],
       [-0.6417622]], dtype=float32), array([7.5024066], dtype=float32)]
第150次迭代产生的w1,w2,b分别是: [array([[ 2.4844794 ],
       [-0.47561312]], dtype=float32), array([8.336492], dtype=float32)]
第200次迭代产生的w1,w2,b分别是: [array([[ 2.1817584 ],
       [-0.35411417]], dtype=float32), array([8.839961], dtype=float32)]
第250次迭代产生的w1,w2,b分别是: [array([[ 1.9908502 ],
       [-0.27635399]], dtype=float32), array([9.151955], dtype=float32)]
第300次迭代产生的w1,w2,b分别是: [array([[ 1.8715947 ],
       [-0.22765213]], dtype=float32), array([9.346234], dtype=float32)]
第350次迭代产生的w1,w2,b分别是: [array([[ 1.7972252 ],
       [-0.19726674]], dtype=float32), array([9.467321], dtype=float32)]
第400次迭代产生的w1,w2,b分别是: [array([[ 1.750861 ],
       [-0.1783222]], dtype=float32), array([9.542803], dtype=float32)]
第450次迭代产生的w1,w2,b分别是: [array([[ 1.721959  ],
       [-0.16651219]], dtype=float32), array([9.589854], dtype=float32)]
第500次迭代产生的w1,w2,b分别是: [array([[ 1.7042251],
       [-0.1592657]], dtype=float32), array([9.618724], dtype=float32)]

 
4 months ago

1.实现一元函数的线性回归

已知6个点:(1,3),(2,4),(3,7),(4,8),(5,11),(6,14)
寻找一条直线y=wx+b,使得这些点沿y轴方向到给直线的距离的平方和最小

2.求解思路

w和b是需要求解的未知量,使用tf.Variable来进行初始化
损失函数loss可以用tf.squaretf.reduce_sum来实现
利用基本的梯度下降tf.train.GradientDescentOptimizer来迭代求解w,b

3.核心代码实现

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

x=tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],tf.float32)
y_true=tf.constant([3.0,4.0,7.0,8.0,11.0,14.0],tf.float32)
w=tf.Variable(tf.constant([4.0],tf.float32))
b=tf.Variable(tf.constant([2.0],tf.float32))
y_predict=w*x+b
loss=tf.reduce_sum(tf.square(y_true-y_predict))
optimer=tf.train.GradientDescentOptimizer(0.01).minimize(loss)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print("w的初始值为:%f" %(sess.run(w)))
    print("b的初始值为:%f" %(sess.run(b)))
    for i in range(5):
        sess.run(optimer)
        print("第%d次迭代后,w、b的值分别为:%f,%f" %(i+1,sess.run(w),sess.run(b)))
        print("第%d次迭代后,损失值为:%f" %(i+1,sess.run(loss)))

运行结果如下:

w的初始值为:4.000000
b的初始值为:2.000000
第1次迭代后,w、b的值分别为:-0.060000,1.020000
第1次迭代后,损失值为:387.479584
第2次迭代后,w、b的值分别为:3.680800,1.862800
第2次迭代后,损失值为:327.183441
第3次迭代后,w、b的值分别为:0.259368,1.033328
第3次迭代后,损失值为:276.348755
第4次迭代后,w、b的值分别为:3.413321,1.740394
第4次迭代后,损失值为:233.489594
第5次迭代后,w、b的值分别为:0.530111,1.037952
第5次迭代后,损失值为:197.353699

4.图形化展示训练过程(完整代码)

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# 1)线性回归
x=tf.constant([1.0,2.0,3.0,4.0,5.0,6.0],tf.float32)
y_true=tf.constant([3.0,4.0,7.0,8.0,11.0,14.0],tf.float32)
w=tf.Variable(tf.constant([4.0],tf.float32))
b=tf.Variable(tf.constant([2.0],tf.float32))
y_predict=w*x+b
loss=tf.reduce_sum(tf.square(y_true-y_predict))
optimer=tf.train.GradientDescentOptimizer(0.01).minimize(loss)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    #print("w的初始值为:%f" %(sess.run(w)))
    #print("b的初始值为:%f" %(sess.run(b)))
    loss_list=[]
    for i in range(50):
        sess.run(optimer)
        #print("第%d次迭代后,w、b的值分别为:%f,%f" %(i+1,sess.run(w),sess.run(b)))
        #print("第%d次迭代后,损失值为:%f" %(i+1,sess.run(loss)))
        ww=sess.run(w)
        bb=sess.run(b)
        loss_list.append(sess.run(loss))

# 2)展示梯度下降过程中损失值变化
#plt.figure(figsize=(10,8))
plt.plot([i+1 for i in range(len(loss_list))],loss_list)
plt.show()

# 3)回归成果展示
aa=np.arange(0,10,0.5)
bb=ww*aa+bb
plt.plot(aa,bb)
with tf.Session() as sess:
    plt.scatter(sess.run(x),sess.run(y_true))
plt.show()

运行结果


 
4 months ago

1.tensorflow求解已知函数梯度

# 求解函数(3*X1+4*X2)**2在点(2,3)处的梯度
# tf.tf.gradients()
import tensorflow as tf
import numpy as np

# 将变量x申请为一个占位符
x = tf.placeholder(tf.float32,(2,1))
w = tf.constant([[3,4]],tf.float32) # 需要两个[]才能表示w的形状为(1,2)
y = tf.matmul(w,x) # matmul是math-multiply的简写
f = tf.pow(y,2)
grad = tf.gradients(f,x)
with tf.Session() as sess:
    sess.run(grad,{x:np.array([[2],[3]])} # 这里的np.array是重点

2.梯度下降算法核心代码

# 对一元函数(x-1)**2实现梯度下降算法
# tf.train.GradientDescentOptimizer()
import tensorflow as tf

# 初始化变量:梯度下降的起始点
x=tf.Variable(4.0,tf.float32)
# 其实,一行代码就可以实现随机梯度下降,是不是很机智😊😊
# x=tf.Variable(tf.random_uniform((1,),minval=-8,maxval=10,dtype=tf.float32))
# 函数
y=tf.pow(x-1,2.0)
# 梯度下降:学习率设置为0.05
opti=tf.train.GradientDescentOptimizer(0.05).minimize(y)
# 创建会话
with tf.Session() as sess:
    # Variable对象初始化
  sess.run(tf.global_variables_initializer())
  print("x的初始值为:",sess.run(x))
  # 三次迭代
  for i in range(3):
    sess.run(opti)
    print("第%d次迭代后的x值为%f" %(i+1,sess.run(x)))

运行结果如下:

x的初始值为: 4.0
第1次迭代后的x值为2.500000
第2次迭代后的x值为1.750000
第3次迭代后的x值为1.375000

3.梯度下降过程的图形化展示

1)首先画出函数(x-1)**2的图像

import matplotlib.pyplot as plt

# 准备x坐标数据
a=np.linspace(-8.0,10.0,100)
# 准备对应的y数据
b=[np.power(i-1,2) for i in a]
# 画图
plt.plot(a,b)
plt.show()


2)梯度下降过程核心代码演示

import matplotlib.pyplot as plt

# 准备x坐标数据
a=[4,2.5,1.75,1.375]
# 准备对应的y数据
b=[np.power(i-1,2) for i in a]
# 画图
plt.plot(a,b)
plt.show()

4.代码合并(一元函数的梯度下降)

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt


# 1)函数图形化展示,数据准备
a=np.linspace(-2,4,100)
b=[np.power(i-1,2) for i in a]

# 2)实现梯度下降
x=tf.Variable(4.0,tf.float32)
y=tf.pow(x-1,2.0)
opti=tf.train.GradientDescentOptimizer(0.25).minimize(y)
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  aa=[]
  xtemp=sess.run(x)
  print("x的初始值为:",xtemp)
  aa.append(xtemp)
  for i in range(3):
    sess.run(opti)
    xtemp=sess.run(x)
    print("第%d次迭代后的x值为%f" %(i+1,xtemp))
    aa.append(xtemp)
    
# 3)梯度下降过程的图形化展示,数据准备
bb=[np.power(i-1,2) for i in aa]

# 4)画图
plt.figure(figsize=(10,8))
plt.plot(a,b)
plt.plot(aa,bb)
plt.grid()
plt.xticks(np.linspace(-2,4,7))
for i in range(len(aa)):
    plt.plot([aa[i],aa[i]],[0,bb[i]],linestyle="--")
# 相当于np.arange(-2,4,1)
plt.show()

5.两元函数的梯度下降

# 以 X1**2+X2**2 为例,初始值为(-4,4)
import tensorflow as tf

# 初始化变量
x1=tf.Variable(-4.0,tf.float32)
x2=tf.Variable(4.0,tf.float32)
# 构造函数
y=tf.square(x1)+tf.square(x2)
# 调用梯度下降算法
grad=tf.train.GradientDescentOptimizer(0.25).minimize(y)
# 创建会话
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print("x1,x2的初始值分别为:%f,%f" %(sess.run(x1),sess.run(x2)))
    for i in range(3):
        sess.run(grad)
        v1=sess.run(x1)
        v2=sess.run(x2)
        print("第%d次迭代后,x1与x2的值分别为:%f,%f" %(i+1,v1,v2))

计算结果如下:

x1,x2的初始值分别为:-4.000000,4.000000
第1次迭代后,x1与x2的值分别为:-2.000000,2.000000
第2次迭代后,x1与x2的值分别为:-1.000000,1.000000
第3次迭代后,x1与x2的值分别为:-0.500000,0.500000

6.多元函数的梯度下降

# 以上代码将两个变量分别进行初始化,若自变量比较多,这种写法就不方便了
# 多自变量应该采取矩阵的形式初始化自变量
# 下面仅以两元函数做示范
import tensorflow as tf

x=tf.Variable(tf.constant([-4.0,4.0],tf.float32))
y=tf.square(x)
grad=tf.train.GradientDescentOptimizer(0.25).minimize(y)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print("x的初始值为:",end="")
    print(sess.run(x))
    for i in range(3):
        sess.run(grad)
        print("第%d次迭代后,x的值为:" %(i+1),end="")
        print(sess.run(x))

运算结果为:

x的初始值为:[-4.  4.]
第1次迭代后,x的值为:[-2.  2.]
第2次迭代后,x的值为:[-1.  1.]
第3次迭代后,x的值为:[-0.5  0.5]
 
4 months ago

1.遇到什么问题

我在使用ipic图床时遇到一个小问题,直接上图来说

原始图片是酱紫的


上传后发现图片左侧和下侧的坐标数字被盖住了

2.问题如何解决

我将问题提交到ipic官网,得到工作人员的简单回复


由此了解到两个新知识
1)图片的透明度
通常我们认为图片只有RGB三个维度
此外,图像还包含第四个不可见通道,即包含透明度信息的 Alpha 通道。有时,此类图像称为 RGBA 图像

这个透明度之前在做图片展示的时候是有发现的,该图片数据为4通道(当时很困惑,但是没办法想太多)


原始图片是这样的

查看该图片的属性,确实发现有透明度信息(即alpha通道)

2)ipic图床默认使用微博图床,微博图床只支持jpg格式
不管用户上传什么格式的图片,微博会转换成jpg格式的图片返回给用户
也就是说原始图片是带有透明度信息的,图床在转换的过程中丢失了透明度通道,由此导致坐标数字被掩盖的现象

3.如何解决

从原始图片着手,去除透明度信息
最简单的办法就是不要直接上传原始图片,先截屏后(截屏软件丢掉了原始图片的透明度信息)再上传,问题解决

参考资料:
ipic官方使用教程
新浪微博图床的 Chrome 扩展
关于Alpha通道和遮罩
去除图像中的alpha通道或透明度

 
4 months ago

1.背景知识

1)生活中据大部分数据都满足正态分布,其均值、中位数、众数相等
2)正态分布概率密度公式

2.代码实现

import numpy as np
import matplotlib.pyplot as plt

# 原始数据:先随机生成一个正态分布数组,模拟实际数据(均值为165cm,标准差为10cm的身高数据)
data=np.random.normal(165,10,(1000))

# 实现正态分布概率密度函数
mean=data.mean() # 计算原始数据的均值
std=data.std() # 计算原始数据的标准差
x=list(np.arange(130,200,1))
y=1.0/(np.sqrt(2*np.pi)*std)*np.exp(-np.power((x-mean),2)/2/np.power(std,2))
plt.plot(x,y)
# 显示直方图📊(normed这个参数指定密度,也就是每个条状图的占比,总的比例默认为1)
plt.hist(data,30,normed=True)

plt.show()

结果很完美


参考资料:
均值、众数、中位数不同分布中的值比较
hist的使用

 
4 months ago

1.tensorflow小知识

1)tensorflow中的张量,可以理解为n维数组或者矩阵
2)tensorflow通过创建会话(session),将张量转化为Numpy类型的数组(ndarray)

2.图像读取步骤

1)通过函数tf.read_file读取本地图像文件
2)利用函数tf.image.decode_png解码为张量
不同的文件类型有不同的解码API

3.代码实现

import tensorflow as tf
import matplotlib.pyplot as plt

# 读取图像文件
img = tf.read_file("../data/running_man.png","r")
# 将图像文件解码为tensor
img_tensor=tf.image.decode_png(img)
# 将tensor转换为numpy类型的数组(ndarray)
with tf.Session() as sess:
    img_ndarray = sess.run(img_tensor)
# 查看图片维度
print(img_ndarray.shape)
# 显示图片
plt.imshow(img_ndarray)
plt.show()

大功告成

参考资料:
张平:《图解深度学习与神经网络》

 
4 months ago

1.用Tensorflow实现一个最基本的线性回归

# 假设随机指定100个点,只有一个特征
# 数据本身的分布为 y = 0.7 * x + 0.8

import matplotlib.pyplot as plt
import tensorflow as tf

x_data = tf.random_normal([100, 1], mean=1.0, stddev=1.0, name="x_data")
y_true = tf.matmul(x_data, [[0.7]]) + 0.8
with tf.variable_scope("linea_model"):
    # 建立回归模型,分析别人的数据的特征数量--->权重数量, 偏置b
    # 由于有梯度下降算法优化,所以一开始给随机的参数,权重(按照正态分布赋值)和偏置
    # 被优化的参数,必须得使用变量op去定义
    # 变量初始化权重和偏置
    # weight 2维[1, 1]    bias [1]
    # 变量op当中会有trainable参数决定是否训练
    weight = tf.Variable(tf.random_normal([1, 1], mean=0.0, stddev=1.0),
                             name="weights")

    bias = tf.Variable(0.0, name='biases')

    # 建立回归公式去得出预测结果
    y_predict = tf.matmul(x_data, weight) + bias
loss = tf.reduce_mean(tf.square(y_true - y_predict))
train_op = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # 在没训练,模型的参数值
    print("初始化的权重:%f, 偏置:%f" % (weight.eval(), bias.eval()))
    # 开启训练
    # 训练的步数(依据模型大小而定)
    saver = tf.train.Saver()
    #for i in range(FLAGS.max_step):
    temp=[]
    for i in range(100):
        sess.run(train_op)
        # 生成事件文件,观察图结构
        #file_writer = tf.summary.FileWriter("./tmp/summary/", graph=sess.graph)
        print("训练第%d步之后的损失:%f, 权重:%f, 偏置:%f" % (
            i,
            loss.eval(),
            weight.eval(),
            bias.eval()))
        
        temp.append(loss.eval())
# 展示梯度下降过程
plt.plot([i+1 for i in range(len(temp))],temp)
plt.grid()
plt.show()

2.超参数调参

显然这里的超参数只有学习率learning-rate
1)学习率为0.1


迭代60次后收敛到10的-6次方以下
2)学习率为0.2

迭代30次后收敛到10的-6次方以下
3)学习率为0.3

迭代20次后收敛到10的-6次方以下
4)学习率为0.4

出现的梯度爆炸情况(学习率过大越过了最低点)
5)学习率0.01

迭代100次后收敛到10的-4次方以下

3.结论

论梯度下降求解中,设置学习率的重要性