Python 从头开始制作ML模型时卡住了
我有一个CSV文件,其中包含8个参数,用于确定患者是否患有糖尿病。 您将从中获取CSV文件 我正在制作一个模型,可以在不使用第三方应用程序(如Tensorlfow Scikitlearn等)的情况下训练和预测一个人是否患有糖尿病。我正在从头开始制作 这是我的密码:Python 从头开始制作ML模型时卡住了,python,machine-learning,deep-learning,Python,Machine Learning,Deep Learning,我有一个CSV文件,其中包含8个参数,用于确定患者是否患有糖尿病。 您将从中获取CSV文件 我正在制作一个模型,可以在不使用第三方应用程序(如Tensorlfow Scikitlearn等)的情况下训练和预测一个人是否患有糖尿病。我正在从头开始制作 这是我的密码: from numpy import genfromtxt import numpy as np my_data = genfromtxt('E:/diabaties.csv', delimiter=',') X,Y = my_da
from numpy import genfromtxt
import numpy as np
my_data = genfromtxt('E:/diabaties.csv', delimiter=',')
X,Y = my_data[1: ,:-1], my_data[1: ,-1:] #striping data and output from my_data
def sigmoid(x):
return (1/(1+np.exp(-x)))
m = X.shape[0]
def propagate(W, b, X, Y):
#forward propagation
A = sigmoid(np.dot(X, W) + b)
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
print(cost)
#backward propagation
dw = (1 / m) * np.dot(X.T, (A - Y))
db = (1 / m) * np.sum(A - Y)
return(dw, db, cost)
def optimizer(W,b,X,Y,number_of_iterration,learning_rate):
for i in range(number_of_iterration):
dw, db, cost = propagate(W,b,X,Y)
W = W - learning_rate*dw
b = b - learning_rate*db
return(W, b)
W = np.zeros((X.shape[1],1))
b = 0
W,b = optimizer(W, b, X, Y, 100, 0.05)
生成的输出为:
我已经试过了-
用随机数初始化W的值。
花了很多时间进行调试,但找不到我做错了什么问题在于权重和偏差的初始化。重要的是,至少不要将权重初始化为零,而是使用一些随机的小数字来初始化它们。A的值为零,使成本函数未定义 更新: 试着这样做:
from numpy import genfromtxt
import numpy as np
# my_data = genfromtxt('E:/diabaties.csv', delimiter=',')
# X,Y = my_data[1: ,:-1], my_data[1: ,-1:] #striping data and output from my_data
# Using random data
n_points = 100
n_neurons = 5
X = np.random.rand(n_points, n_neurons) # 5 dimensional data from uniform distribution [0, 1)
Y = np.random.randint(low=0, high=2, size=(n_points, 1)) # Binary labels
def sigmoid(x):
return (1/(1+np.exp(-x)))
m = X.shape[0]
def propagate(W, b, X, Y):
#forward propagation
A = sigmoid(np.dot(X, W) + b)
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
print(cost)
#backward propagation
dw = (1 / m) * np.dot(X.T, (A - Y))
db = (1 / m) * np.sum(A - Y)
return(dw, db, cost)
def optimizer(W,b,X,Y,number_of_iterration,learning_rate):
for i in range(number_of_iterration):
dw, db, cost = propagate(W,b,X,Y)
W = W - learning_rate*dw
b = b - learning_rate*db
return(W, b)
W = np.random.normal(loc=0, scale=0.01, size=(n_neurons, 1)) # Drawing random initialization from gaussian
b = 0
W,b = optimizer(W, b, X, Y, 100, 0.05)
X = minmax_scaler(X)
neurons = 10
learning_rate = 0.05
W = np.random.random((X.shape[1], neurons))
b = np.zeros((1, neurons)) # b width to match W
问题在于权重和偏差的初始化。重要的是,至少不要将权重初始化为零,而是使用一些随机的小数字来初始化它们。A的值为零,使成本函数未定义 更新: 试着这样做:
from numpy import genfromtxt
import numpy as np
# my_data = genfromtxt('E:/diabaties.csv', delimiter=',')
# X,Y = my_data[1: ,:-1], my_data[1: ,-1:] #striping data and output from my_data
# Using random data
n_points = 100
n_neurons = 5
X = np.random.rand(n_points, n_neurons) # 5 dimensional data from uniform distribution [0, 1)
Y = np.random.randint(low=0, high=2, size=(n_points, 1)) # Binary labels
def sigmoid(x):
return (1/(1+np.exp(-x)))
m = X.shape[0]
def propagate(W, b, X, Y):
#forward propagation
A = sigmoid(np.dot(X, W) + b)
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
print(cost)
#backward propagation
dw = (1 / m) * np.dot(X.T, (A - Y))
db = (1 / m) * np.sum(A - Y)
return(dw, db, cost)
def optimizer(W,b,X,Y,number_of_iterration,learning_rate):
for i in range(number_of_iterration):
dw, db, cost = propagate(W,b,X,Y)
W = W - learning_rate*dw
b = b - learning_rate*db
return(W, b)
W = np.random.normal(loc=0, scale=0.01, size=(n_neurons, 1)) # Drawing random initialization from gaussian
b = 0
W,b = optimizer(W, b, X, Y, 100, 0.05)
X = minmax_scaler(X)
neurons = 10
learning_rate = 0.05
W = np.random.random((X.shape[1], neurons))
b = np.zeros((1, neurons)) # b width to match W
这个简短的回答是,对于这个问题来说,你的学习率大约是500倍。想象一下,就像你试图将你的
W
向量引入成本函数中的峡谷一样。在每一步,坡度告诉你哪条路是下坡路,但是你在那个方向上走的台阶太大了,以至于你跳过峡谷,最后到了另一边。每次发生这种情况,您的成本都会上升,因为您离峡谷越来越远,直到经过2次迭代后,峡谷爆炸
如果你换一条线
W,b=优化器(W,b,X,Y,100,0.05)
与
W,b=优化器(W,b,X,Y,100,0.0001)
它将收敛,尽管速度仍然不合理。(请注意,对于给定的问题,没有好的方法可以知道您需要的学习率。您只需尝试越来越低的值,直到您的成本值不会出现差异。)
较长的答案是,问题在于你的特征都在不同的尺度上
col_means = X.mean(axis=0)
col_stds = X.std(axis=0)
print('column means: ', col_means)
print('column stdevs: ', col_stds)
屈服
column means: [ 3.84505208 120.89453125 69.10546875 20.53645833 79.79947917
31.99257812 0.4718763 33.24088542]
column stdevs: [ 3.36738361 31.95179591 19.34320163 15.94182863 115.16894926
7.87902573 0.33111282 11.75257265]
这意味着第二个特征的数量变化大约是第二个到最后一个特征数量变化的100倍,这反过来意味着W
向量中第二个值的数量必须调整为第二个到最后一个特征的数值精度的约100倍W
vector
在实践中有两种方法可以解决这个问题。首先,您可以使用更高级的优化器。您可以使用带有动量的梯度下降,而不是基本的梯度下降,但这会改变您所有的代码。第二种更简单的方法是调整功能,使其大小大致相同
col_means = X.mean(axis=0)
col_stds = X.std(axis=0)
print('column means: ', col_means)
print('column stdevs: ', col_stds)
X -= col_means
X /= col_stds
W, b = optimizer(W, b, X, Y, 100, 1.0)
这里我们减去每个特征的平均值,然后用每个特征的值除以其标准偏差。有时新手会被这句话吓坏——“你不能改变你的数据值,这会改变问题”——但如果你意识到这只是另一个数学变换,就像乘以W,加上b,取s形,等等。唯一的问题是,你必须确保你对未来的数据做同样的事情。正如W
向量的值是模型的学习参数一样,col\u的值也意味着和col\u std
的值也是,因此您必须像W
和b
那样保存它们,如果您想在将来使用此模型对新数据进行推断,请使用它们
这让我们可以使用更大的学习评分器1.0,因为现在所有功能的大小都差不多
col_means = X.mean(axis=0)
col_stds = X.std(axis=0)
print('column means: ', col_means)
print('column stdevs: ', col_stds)
X -= col_means
X /= col_stds
W, b = optimizer(W, b, X, Y, 100, 1.0)
现在,如果您尝试,您将获得以下输出:
column means: [ 3.84505208 120.89453125 69.10546875 20.53645833 79.79947917
31.99257812 0.4718763 33.24088542]
column stdevs: [ 3.36738361 31.95179591 19.34320163 15.94182863 115.16894926
7.87902573 0.33111282 11.75257265]
0.6931471805599452
0.5902957589079032
0.5481784378158732
0.5254804089153315
...
0.4709931321295562
0.4709931263193595
0.47099312122176273
0.4709931167488006
0.470993112823447
这就是你想要的。您的成本函数在每一步都会下降,在100次迭代结束时,成本稳定在~8个有效数字,因此降低成本可能不会有多大作用
欢迎来到机器学习 这个简短的答案是,对于这个问题来说,你的学习速度大约是500倍。想象一下,就像你试图将你的W
向量引入成本函数中的峡谷一样。在每一步,坡度告诉你哪条路是下坡路,但是你在那个方向上走的台阶太大了,以至于你跳过峡谷,最后到了另一边。每次发生这种情况,您的成本都会上升,因为您离峡谷越来越远,直到经过2次迭代后,峡谷爆炸
如果你换一条线
W,b=优化器(W,b,X,Y,100,0.05)
与
W,b=优化器(W,b,X,Y,100,0.0001)
它将收敛,尽管速度仍然不合理。(请注意,对于给定的问题,没有好的方法可以知道您需要的学习率。您只需尝试越来越低的值,直到您的成本值不会出现差异。)
较长的答案是,问题在于你的特征都在不同的尺度上
col_means = X.mean(axis=0)
col_stds = X.std(axis=0)
print('column means: ', col_means)
print('column stdevs: ', col_stds)
屈服
column means: [ 3.84505208 120.89453125 69.10546875 20.53645833 79.79947917
31.99257812 0.4718763 33.24088542]
column stdevs: [ 3.36738361 31.95179591 19.34320163 15.94182863 115.16894926
7.87902573 0.33111282 11.75257265]
这意味着第二个特征的数量变化大约是第二个到最后一个特征数量变化的100倍,这反过来意味着W
向量中第二个值的数量必须调整为第二个到最后一个特征的数值精度的约100倍W
vector
在实践中有两种方法可以解决这个问题。首先,您可以使用更高级的优化器。您可以使用带有动量的梯度下降,而不是基本的梯度下降,但这会改变您所有的代码。第二种更简单的方法是调整功能,使其大小大致相同
col_means = X.mean(axis=0)
col_stds = X.std(axis=0)
print('column means: ', col_means)
print('column stdevs: ', col_stds)
X -= col_means
X /= col_stds
W, b = optimizer(W, b, X, Y, 100, 1.0)
这里我们减去每个特征的平均值,然后用每个特征的值除以其标准偏差。有时新手会被这件事吓跑--