SkLearn中MLP结合GridSearchCV调参

Multi-layer Perceptron即多层感知器,也就是神经网络,要说它的Hello world,莫过于识别手写数字了。如果你已经了解它的原理并尝试过自己写一个后就可以试用下通用的类库,好将来用在生产环境。下面是使用SkLearn中的MLPClassifier识别手写数字,代码是在Python2.7上运行。
首先获取数据集,我是在http://www.iro.umontreal.ca/~lisa/deep/data/mnist/mnist.pkl.gz下载的,也可以直接搜索mnist.pkl.gz来获取。数据集大小可能有区别,但数组中的每一行都表示一个灰度图像。每个元素都表示像素所对应的灰度值。
先来初步查看下数据

from sklearn.neural_network import MLPClassifier
import numpy as np
import pickle
import gzip
import matplotlib.pyplot as plt

加载数据

with gzip.open(r"mnist.pkl.gz") as fp:
training_data, valid_data, test_data = pickle.load(fp)

X_training_data, y_training_data = training_data
X_valid_data, y_valid_data = valid_data
X_test_data, y_test_data = test_data

def show_data_struct():
print X_training_data.shape, y_training_data.shape
print X_valid_data.shape, y_valid_data.shape
print X_test_data.shape, y_test_data.shape
print X_training_data[0]
print y_training_data[0]

show_data_struct()
重点注意数据已经归一化,就是把数值映射到0到1之间,这对于mlp是很有必要的。

为什么要把数据分为训练集,测试集?
另外这里把数据分为了三类,分别为训练集,验证集,测试集。大多数时候是分为训练集和测试集。当然如果我们直接收集到的数据没有分开,训练模型时要自己分为训练集和测试集。
将原始数据分开,保证用于测试的数据是训练模型时从未遇到的数据可以使测试更客观。否则就像学习教课书的知识,又只考教课书的知识,就算不理解记下了就能得高分但遇到新问题就傻眼了。
好一点的做法就是用训练集当课本给他上课,先找出把课本知识掌握好的人,再参加由新题组成的月考即测试集,若是还是得分高,那就是真懂不是死记硬背了。
但这样选出来的模型实际是还是用训练集和测试集共同得到的,再进一步,用训练集和验证集反复训练和检测,得到最好的模型,再用测试集来一局定输赢即期末考试,这样选出来的就更好了。
这里就不搞这么复杂了,将training,validation合并,把数据分为训练集和测试集。
接下来先看下这些手写数字长什么样。

from sklearn.neural_network import MLPClassifier
import numpy as np
import pickle
import gzip
import matplotlib.pyplot as plt

加载数据

with gzip.open(r"mnist.pkl.gz") as fp:
training_data, valid_data, test_data = pickle.load(fp)

X_training_data, y_training_data = training_data
X_valid_data, y_valid_data = valid_data
X_test_data, y_test_data = test_data

合并训练集,验证集

X_training = np.vstack((X_training_data, X_valid_data))
y_training = np.append(y_training_data, y_valid_data)

def show_image():
plt.figure(1)
for i in range(10):
image = X_training[i]
pixels = image.reshape((28, 28))
plt.subplot(5,2,i+1)
plt.imshow(pixels, cmap=‘gray’)
plt.title(y_training[i])
plt.axis(‘off’)
plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.45,
wspace=0.85)
plt.show()

show_image()
Figure_1.png

这是测试集中的前10个数字,一眼就可以看出写的是什么。注意在上面的代码有一行是把图片对应的一行数据转为28 *28的二维数组,这个不转不行啊!把任何一个图片每行首尾相连,看一个1个像素高768个像素宽的图片,那可没办法知道写的是什么。那么问题来了,我们人看到的是一个二维的图片,而给模型输入的是个一维数组,丢失了原始图片的长宽比例信息,这样它还能识别出来吗?
呃呃呃,哦----,哦-----。当我说这些时你知道我想表示不知道,对不对?我们约定好一分钟内前30秒滴滴滴后30秒哒哒哒表示1,前20秒哒哒哒后40秒滴滴滴表示2,这样用一连串声音信号就能表示数字信息了。同样将图片从上到下从左到右逐个像素填到一个长度为768的向量,变成一个像素高度的图片,从左到右看过去就是一会儿白一会儿黑,就像刚才说的声音一样,它也能表示不同的数字。所以模型识别的并不是原始的图片而是转换后的一个向量。
现在就来看看效果

from sklearn.neural_network import MLPClassifier
import numpy as np
import pickle
import gzip
import matplotlib.pyplot as plt

加载数据

with gzip.open(r"mnist.pkl.gz") as fp:
training_data, valid_data, test_data = pickle.load(fp)

X_training_data, y_training_data = training_data
X_valid_data, y_valid_data = valid_data
X_test_data, y_test_data = test_data

合并训练集,验证集

X_training = np.vstack((X_training_data, X_valid_data))
y_training = np.append(y_training_data, y_valid_data)

def train():
mlp = MLPClassifier()
# 查看默认超参
print mlp
# 训练模型
mlp.fit(X_training, y_training)
print(mlp.score(X_test_data, y_test_data))

train()
我测试的分数是0.9807,还不低是不是?现在全用默认参数,如果再优化下,还能不能再提高些呢?下面用gridSearchCV来试下。

from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import GridSearchCV
import numpy as np
import pickle
import gzip
import matplotlib.pyplot as plt

if name == ‘main’:
# 加载数据
with gzip.open(r"mnist.pkl.gz") as fp:
training_data, valid_data, test_data = pickle.load(fp)

X_training_data, y_training_data = training_data
X_valid_data, y_valid_data = valid_data
X_test_data, y_test_data = test_data
# 合并训练集,验证集
X_training = np.vstack((X_training_data, X_valid_data))
y_training = np.append(y_training_data, y_valid_data)
mlp_clf__tuned_parameters = {"hidden_layer_sizes": [(100,), (100, 30)],
                             "solver": ['adam', 'sgd', 'lbfgs'],
                             "max_iter": [20],
                             "verbose": [True]
                             }
mlp = MLPClassifier()
estimator = GridSearchCV(mlp, mlp_clf__tuned_parameters, n_jobs=6)
estimator.fit(X_training, y_training)

print estimator.get_params().keys()
print estimator.best_params_

这里的max_iter是想让它快些结束才设置为20默认是200,这样得到的最优参数自然不是真正的最优参数。这里虽然只调两个参数,排列组合得到的6种情况并行计算,还是很卡很慢。实际调参要先明白各参数的含义,预先猜测最好的值去测试,还要借助其它方法才能快速有效的调参。

作者:多问Why
链接:https://www.jianshu.com/p/d4fd9c52a915
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

SklearnMLP(多层感知器)是一种人工神经网络模型,用于解决分类和回归问题。MLP模型由多个全连接的神经元层组成,其每个神经元都与下一层的神经元相连。它是一种前馈神经网络,意味着信息从输入层流向输出层,没有循环连接。 在sklearnMLP模型可以通过`sklearn.neural_network.MLPClassifier`(分类问题)和`sklearn.neural_network.MLPRegressor`(回归问题)类来实现。MLP模型的训练过程使用反向传播算法,并且可以自定义多个参数,如隐藏层的数量和大小、激活函数、优化算法等。 以下是一个使用MLPClassifier进行分类任务的示例代码: ```python from sklearn.neural_network import MLPClassifier from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split # 生成样本数据 X, y = make_classification(n_samples=100, random_state=1) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1) # 创建MLP分类器 mlp = MLPClassifier(hidden_layer_sizes=(10,), max_iter=1000) # 训练模型 mlp.fit(X_train, y_train) # 预测测试集 y_pred = mlp.predict(X_test) # 评估模型 accuracy = mlp.score(X_test, y_test) print("Accuracy:", accuracy) ``` 在上面的示例,我们生成了一个包含100个样本的分类任务的数据集,并将其划分为训练集和测试集。然后,我们创建了一个具有一个包含10个神经元的隐藏层的MLPClassifier,并使用训练集进行训练。最后,我们使用测试集进行预测,并计算模型的准确率。 你还有其他关于sklearnMLP模型的问题吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值