我对机器学习还比较陌生,最开始是通过阅读《Machine Learning: An Algorithmic Perspective》这本书来学习的。我试图通过修改书籍网站上提供的代码,创建一个能够区分恶意程序和良性程序的逻辑分类器。然而,即使经过100000个周期,隐藏层和输出层的权重也没有发生变化。
我尝试过使用完整的数据集以及部分数据集运行算法,但仍然没有效果。
这是我的多层感知器类
代码内容保持不变
这是我的调用代码,提供数据
代码内容保持不变
每个向量有7个维度,最后一个条目是目标值
这是包含数据集的完整文本文件的链接https://drive.google.com/open?id=1q_aGNgHxTBh_mmVAzVXKBa27NTJKeKV8
请告诉我我哪里做错了。如果有易于使用的库可以完成同样的任务,请推荐一下。
回答:
正如评论中提到的,随机初始化网络权重应该能使网络进行训练。
# 初始化网络
self.weights1 = (np.random.rand(self.nin+1,self.nhidden)-0.5)*2/np.sqrt(self.nin)
self.weights2 = (np.random.rand(self.nhidden+1,self.nout)-0.5)*2/np.sqrt(self.nhidden)
然后,从你的数据来看,属性之间完全不可比。这意味着你的网络梯度更新将由单一特征主导。为了解决这个问题,一个选择是标准化你的数据。
from sklearn.preprocessing import StandardScaler
for i in range(apk_train_data.shape[1]-1):
scaler = StandardScaler().fit(apk_train_data[:,i].copy())
apk_train_data[:,i] = scaler.transform(apk_train_data[:,i].copy())
apk_test_data[:,i] = scaler.transform(apk_test_data[:,i].copy())
最后但同样重要的是,eta
设为0.25太大了。我将通过使用相反的极端情况来进行说明:
p.mlptrain(apk_train_data[:, 0:7], apk_train_data[:, 7:], 0.0001, 100000)
p.confmat(apk_test_data[:, 0:7], apk_test_data[:, 7:])
# >> Percentage Correct: 71.4285714286
p.confmat(apk_train_data[:,0:7], apk_train_data[:,7:])
# >> Percentage Correct: 88.8888888889