基于神经网络的二分类问题
在之前的文章中,介绍了神经网络的概念和算法思想,甚至给出了公式推导。但依然没有掌握神经网络的精髓,于是打算进一步学习就在网上观看了吴恩达大佬的《神经网络和深度学习》这门课程,觉得收获很大。目前只学习了单个神经元的原理及应用,下面简单总结一下。1. 损失函数的定义 与之前介绍的单个神经元的工作原理不同之处在于损失函数的定义,这里把损失函数定义为: 推导思路:利用
在之前的文章中,介绍了神经网络的概念和算法思想,甚至给出了公式推导。但依然没有掌握神经网络的精髓,于是打算进一步学习就在网上观看了吴恩达大佬的《神经网络和深度学习》这门课程,觉得收获很大。目前只学习了单个神经元的原理及应用,下面简单总结一下。
1. 损失函数的定义
与之前介绍的单个神经元的工作原理不同之处在于损失函数的定义,这里把损失函数定义为:
推导思路:利用最大似然估计。先表达出p(y|x),然后求其最大值。大致推导过程如下:
课程中另一个重点是“消除for循环”,也就是说用向量来代替显示的for循环,这样做的好处是提高计算效率。实验测试100万条测试数据,向量化要比循环快上300倍。因此在以后的编码中,尽量把数据初始化成一个矩阵来处理。在这里值得注意的是,构造的矩阵应该每一列表示一个测试样例。
2. 代码实现
下面给出基于神经网络的二分类代码(python):
import numpy as np
import h5py
import math
def load_dataset():
train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels
test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels
classes = np.array(test_dataset["list_classes"][:]) # the list of classes
train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
def train_model(learning_rate=0.1):
train_data_x, train_data_y, test_data_x, test_data_y, classes = load_dataset() # 获取数据集
train_data_x = train_data_x.reshape(209, 64*64*3).T # 把训练数据构造成二维矩阵,行数为X的维度,列值为训练样本的个数
row_count = 64*64*3 # 表示一个样例的维度
examples_count = 209 # 表示样例的数量
weight = np.zeros((64*64*3, 1)) # 初始化权值向量为0
b = 0 # 初始化阈值为0
dw = 0
db = 0
for i in range(1000):
z = np.dot(weight.T, train_data_x) + b # 计算z
y_hat = 1.0 / (1 + math.e**(-z)) # 计算预测值
result = np.sum(abs(y_hat - train_data_y )) # 以累加y_hat-y的值来表示预测效果,result越小越好
if result == 0:
break
print '%d:%d' %(i, result)
dz = y_hat - train_data_y # 计算dL/dz
dw = np.dot(train_data_x, dz.T) # 计算dL/dw
db = np.sum(dz)
dw = dw * 1.0 / examples_count
db = db * 1.0 / examples_count
weight = weight - learning_rate * dw
b = b - learning_rate * db
return weight, b
def predict_data(weight, b):
train_data_x, train_data_y, test_data_x, test_data_y, classes = load_dataset() # 获取数据集
row_count = 64 * 64 * 3 # 一个样例的维度
example_count = 50 # 测试样例个数
test_data_x = test_data_x.reshape(example_count, row_count).T # 转换成对应格式的矩阵
z = np.dot(weight.T, test_data_x) + b
predict_y = 1.0 / (1 + math.e**(-z)) # 计算预测值
print 'correct rate:',np.sum(predict_y == test_data_y)* 1.0 / example_count
print predict_y
if __name__ == '__main__':
train_data_x, train_data_y, test_data_x, test_data_y, classes = load_dataset() # 获取数据集
weight, b = train_model(learning_rate = 0.1) # 训练参数
predict_data(weight, b) # 根据训练的参数进行预测
这里有一点需要注意,在构造矩阵的时候"test_data_x = test_data_x.reshape(example_count, row_count).T"并不等价于"test_data_x = test_data_x.reshape(row_count,example_count)",如果直接用第二个语句,则会打乱原来每个样例的数据,构造的矩阵毫无实际意义。
在该测试样例中,训练时大概需要迭代600多次即可收敛,最后预测的准确率约为:72%。
更多推荐
所有评论(0)