深度学习笔记-Neural Networks and Deep Learning-3-1个隐藏层分类

Neural Networks and Deep Learning:https://www.coursera.org/learn/neural-networks-deep-learning/home/week/3

这段时间会一直更深度学习的内容。
先明确说明代码不是我写的,我只是整理,来源于Cousera的代码,将代码大幅度缩短,补充说明。

还是分成三段,
-1是效果
0.代码
1.扩展和补充

-1.效果

在这里插入图片描述

0.代码

import numpy as np
import matplotlib.pyplot as plt
import sklearn
import sklearn.datasets
import sklearn.linear_model

np.random.seed(1)


# 生成数据集X,Y
np.random.seed(1)
m = 400                                   # 数据量
N = int(m/2)                              # 每一个分类的point数量
D = 2                                     # 维度
X = np.zeros((m,D))                       # 0向量                        (400,2)
Y = np.zeros((m,1), dtype='uint8')        # 标签 (0 for red,1 for blue)  (400,1)
a = 4 # maximum ray of the flower



for j in range(2):
    ix = range(N*j,N*(j+1))
    t = np.linspace(j*3.12,(j+1)*3.12,N) + np.random.randn(N)*0.2 # theta
    r = a*np.sin(4*t) + np.random.randn(N)*0.2 # radius
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    Y[ix] = j

X = X.T                                   #                              (2,400)
Y = Y.T                                   #                              (1,400)

# 数据可视化
# 前两项是位置,c是标量用来配色,s大小,cmap配色方案
plt.scatter(X[0, :], X[1, :], c=Y.reshape(400), s=40, cmap=plt.cm.Spectral)



# logistic 预测
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X.T, Y.T)

def plot_decision_boundary(model, X, y):
    x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1    # 填充的边界大于最外边的点,不+1会留白
    y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
    h = 0.01
    
    # 网格化
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

    # 对整个平面网格所在的位置的点进行预测分类
    Z = model(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    # 绘制等值区域和训练集
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.ylabel('x2')
    plt.xlabel('x1')
    plt.scatter(X[0, :], X[1, :], c=y, cmap=plt.cm.Spectral)
    
plot_decision_boundary(lambda x: clf.predict(x), X, Y.reshape(-1))
plt.title("Logistic Regression")

# logistic精度
LR_predictions = clf.predict(X.T)
print ('logistic 的精度: %d ' % float((np.dot(Y,LR_predictions) + np.dot(1-Y,1-LR_predictions))/float(Y.size)*100) +
       '% ' + "(正确率)")



# 深度学习模块
sigmoid = lambda x:1/(1+np.exp(-x))
def nn_model(X, Y, n_h, num_iterations = 10000,learning_rate = 1.2,print_cost=False):
    np.random.seed(3)
    n_x = X.shape[0]
    n_y = Y.shape[0]      
    
    # 参数初始化
    np.random.seed(2) 
    W1 = np.random.randn(n_h, n_x)*0.01
    b1 = np.zeros((n_h, 1))
    W2 = np.random.randn(n_y, n_h)*0.01
    b2 = np.zeros((n_y, 1))
    parameters = {"W1": W1,"b1": b1,"W2": W2,"b2": b2}

    for i in range(0, num_iterations):
        
        # 前向传播
        Z1 = np.dot(W1,X) + b1
        A1 = np.tanh(Z1)
        Z2 = np.dot(W2,A1) + b2
        A2 = sigmoid(Z2)

        # 计算损失函数
        m = Y.shape[1] # number of example
        logprobs = Y*np.log(A2)+(1-Y)*np.log(1-A2)
        cost = - np.sum(logprobs)/m
        cost = np.squeeze(cost)     # 清除维度冗余 E.g., turns [[17]] into 17 

        # 反向传播
        dZ2 = A2 - Y
        dW2 = 1/m * np.dot(dZ2,A1.T) 
        db2 = 1/m * np.sum(dZ2,axis=1,keepdims=True)
        dZ1 = np.dot(W2.T,dZ2)*(1-np.tanh(Z1)**2)
        dW1 = 1/m * np.dot(dZ1,X.T)
        db1 = 1/m * np.sum(dZ1,axis=1,keepdims=True)
        
        # 参数更新
        W1,W2 = W1 - learning_rate * dW1, W2 - learning_rate * dW2
        b1,b2 = b1 - learning_rate * db1, b2 - learning_rate * db2
        parameters = {"W1": W1,"b1": b1,"W2": W2,"b2": b2}  # 完成一次参数更新并重新赋值

        if print_cost and i % 1000 == 0:
            print ("迭代 %i 次后cost: %f" %(i, cost))

    return parameters

# 预测模块
def predict(parameters, X):
    W1,W2 = parameters['W1'],parameters['W2']
    b1,b2 = parameters['b1'],parameters['b2']

    Z1 = np.dot(W1,X) + b1
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2,A1) + b2
    A2 = sigmoid(Z2)    
    
    return np.around(A2,0)

parameters = nn_model(X, Y, n_h = 4, num_iterations = 10000, print_cost=True)

# 绘制决策边界
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y.reshape(-1))
plt.title("Decision Boundary for hidden layer size " + str(4))


# 使用训练后的参数计算数据集
predictions = predict(parameters, X)
print ('预测精度: %d' % float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100) + '%')



# 隐藏大小层对精度的影响
# 隐藏层尺寸是一个超参
plt.figure(figsize=(16, 32))
hidden_layer_sizes = [1, 2, 3, 4, 5, 20, 50]

for i, n_h in enumerate(hidden_layer_sizes):
    plt.subplot(5, 2, i+1)   # 绘制子图
    plt.title('Hidden Layer of size %d' % n_h)
    parameters = nn_model(X, Y, n_h, num_iterations = 5000)
    plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y.reshape(-1)) # 绘制边界
    predictions = predict(parameters, X)
    accuracy = float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
    print ("大小为{}的隐藏层,最后的精度: {} %".format(n_h, accuracy))



# 不同的数据集
def load_extra_datasets():  
    N = 200
    noisy_circles = sklearn.datasets.make_circles(n_samples=N, factor=.5, noise=.3)
    noisy_moons = sklearn.datasets.make_moons(n_samples=N, noise=.2)
    blobs = sklearn.datasets.make_blobs(n_samples=N, random_state=5, n_features=2, centers=6)
    gaussian_quantiles = sklearn.datasets.make_gaussian_quantiles(mean=None, cov=0.5, n_samples=N, n_features=2, n_classes=2, shuffle=True, random_state=None)
    no_structure = np.random.rand(N, 2), np.random.rand(N, 2)
    return noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure
noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure = load_extra_datasets()

datasets = {"noisy_circles": noisy_circles,
            "noisy_moons": noisy_moons,
            "blobs": blobs,
            "gaussian_quantiles": gaussian_quantiles}

dataset = "gaussian_quantiles"

X, Y = datasets[dataset]
X, Y = X.T, Y.reshape(1, Y.shape[0])

# make blobs binary
if dataset == "blobs":
    Y = Y%2

# 数据可视化
plt.scatter(X[0, :], X[1, :], c=Y.reshape(200), s=40, cmap=plt.cm.Spectral)

1.代码说明及扩展

这次的代码里面用到了sklearn,np.random.seed

1.0plt.scatter(X[0, :], X[1, :], c=Y.reshape(400), s=40, cmap=plt.cm.Spectral)

说明:X是绘制的点的位置,Y是这个点的标签,在这里面前200个对应Y里面的0,后200个对应Y里面的1,所以一旦绘图,就会因为01的标量值不同而呈现颜色不同。
具体:这里用了matplotlib的scatter用法
plt.scatter(x, y, s=area, c=colors, alpha=0.5)
1.X.shape维度是(2, 400),前两项分别取了0行1行,表示坐标位置xy
2.c为color类似于mayavi的标量,接受了一个Y.reshape(400),注意Y本身是array([[0, 0, 0, 0,......,1,1,1,1]]),
Y.shape是(1,400)这个和(400,)是有区别的,所以做了一步reshape,另外Y.reshape(400)不如Y.reshape(-1),数据尺寸是变化的。
这里面全是01,具体是,前200项是0,后200项是1
3.cmap配色方案,等效于colormap,字面翻译就是光谱(怪不得这么眼熟。),这个参数去掉也不会报错的,采取默认配色。(BTW:c=np.random.rand(400)是五颜六色的发发,炒鸡好看)
4.s是大小,也是一个可省略参数。

1.1.np.random.seed(1)
这个是产生随机数用的,只是如果加了这一句,下面产生的随机数就能固定下来,
举个栗子好了
在这里插入图片描述
np.random.seed(1)这句下面有1句随机生成,
np.random.seed(20)这句下面有2句随机生成,
按理说循环3次是生成不同的随机,但因为加了这句np.random.seed(1),所以下面的随机数被固定了下来。
注意到这3次循环,每次循环的最后一个随机和第2个随机是不同的,这是因为np.random.seed(20)的作用范围是最近的一句。

1.2.sklearn.linear_model.LogisticRegressionCV()

原代码中有这么一句:
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X.T, Y.T)
说明: 先对象化,再使用fit方法,拟合。
详解: 文档在这里
sklearn.linear_model.LogisticRegressionCV(Cs=10, fit_intercept=True, cv=’warn’, dual=False, penalty=’l2’, scoring=None, solver=’lbfgs’, tol=0.0001, max_iter=100, class_weight=None, n_jobs=None, verbose=0, refit=True, intercept_scaling=1.0, multi_class=’warn’, random_state=None)
这玩意的省略参数也不少,求解方式lbfgs,最大迭代次数都有的,详细看文档。
然后使用了一个fit方法:
fit(X, y[, sample_weight])根据训练集拟合
格式:
X : {array-like, sparse matrix}, shape (n_samples, n_features)
y : array-like, shape (n_samples,)
一般我们习惯把训练集数量记为m,特征数目为n,X的维度就是(m,n)
对应y的维度为(m,1)
注意我们开始得到的X.shape是(2, 400),为(n,m)结构,所以转置。
Y.shape是(1,400),(1,m)结构,所以同样转置。
后面还有一个
clf.predict(x),根据训练好的模型把X重新放进去进行测试。

1.3.np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
这个是用来绘制网格的。

1.4np.c_[xx.ravel(), yy.ravel()]
https://docs.scipy.org/doc/numpy/reference/generated/numpy.r_.html#numpy.r_

补充说明一下:
这段最容易让人看不懂的地方:

# 生成数据集X,Y
np.random.seed(1)
m = 400                                   # 数据量
N = int(m/2)                              # 每一个分类的point数量
D = 2                                     # 维度
X = np.zeros((m,D))                       # 0向量                        (400,2)
Y = np.zeros((m,1), dtype='uint8')        # 标签 (0 for red,1 for blue)  (400,1)
a = 4 # maximum ray of the flower

for j in range(2):
    ix = range(N*j,N*(j+1))               # 0-199,200-399
    t = np.linspace(j*3.14,(j+1)*3.14,N) + np.random.randn(N)*0.2 # theta
    r = a*np.sin(4*t) + np.random.randn(N)*0.2 # radius
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    Y[ix] = j

这段其实把随机去掉,绘图就很明显了。

for j in range(2):
    ix = range(N*j,N*(j+1))               # 0-199,200-399
    t = np.linspace(j*3.14,(j+1)*3.14,N) 
    r = a*np.sin(4*t) 
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    Y[ix] = j

在这里插入图片描述
就这个图案本身而言是用的参数方程画的,一个轨迹方程。然后它给这个轨迹加了很多随机。

{ x = 4 s i n 4 t ⋅ s i n t y = 4 s i n 4 t ⋅ c o s t \begin{cases} x=&4sin4t·sint\\ &&\\ y=&4sin4t·cost& \end{cases} x=y=4sin4tsint4sin4tcost

2.总结

先说一下,和-2.无隐藏层识别猫不同

相对于无隐藏层,多一个隐藏层就多了很多超参Hyperparameters。
1.学习速率lr
在这里插入图片描述
2.迭代次数num_iterations
3.隐藏层的层数
4.每一个隐藏层的大小hidden_layer_sizes
取[1, 2, 3, 4, 5,… 20, 50]的识别精度是不同的,

大小为1的隐藏层,最后的精度: 67.5 %
大小为2的隐藏层,最后的精度: 67.25 %
大小为3的隐藏层,最后的精度: 90.75 %
大小为4的隐藏层,最后的精度: 90.5 %
大小为5的隐藏层,最后的精度: 91.25 %
大小为6的隐藏层,最后的精度: 90.25 %
大小为7的隐藏层,最后的精度: 91.25 %
大小为8的隐藏层,最后的精度: 91.0 %
大小为9的隐藏层,最后的精度: 90.0 %
大小为10的隐藏层,最后的精度: 90.25 %
大小为20的隐藏层,最后的精度: 90.0 %
大小为50的隐藏层,最后的精度: 90.75 %

到后面已经慢慢进入过拟合状态了,最好的时候是91.25%。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值