Newton's second law learn how to use Python to teach the machine?

Common expression of Newton's second law as follows:
acceleration of an object is directly proportional with the size of the force is inversely proportional with the quality of the object, and proportional to the reciprocal of the mass of the object.

Binding Newton's second law we have learned, we know the relationship between the acceleration force F a and the object should be a linear relationship, so we hypothesize a = w * F, and 5 experiments, different statistics of under an acceleration force block as follows:
Here Insert Picture Description
we will soon come w is 2, the training by a large number of experimental data, we can determine the quality of the object parameter w is the reciprocal (1 / m)

This is the people's thinking, change for the machine, how can we change the machine to determine the parameters of the model w is the reciprocal of the mass of the object of it?

The student machine as a machine, only to learn (model parameters w) by attempting to answer (to minimize losses) large number of exercises (known samples), the learning is desirable to form a complete model knowledge w H (θ, X), so that the model can not know the answer to answer the test questions (unknown sample)

In the case of Newton's second law, based on the observation of the data, we propose that the linear assumption that the force and acceleration is linear relationship is represented by a linear equation.

Therefore, before teaching machine learning Newton's second law, we need to create experimental data of Newton's second law:

def creat_npy():
    arr = []
    for i in range(1,1001):
        arr.append(i)
        arr.append(2 * i)
    arr = np.array(arr)
    # print(arr)
    np.save('arr.npy', arr)

creat_npy()

Here Insert Picture Description
We first created with a list of experimental data, each data including the two, namely, acceleration and force, item 0-1 is the first data, item 2-3 is the second data, ...

Such data certainly can not be directly used, we need to process the data:

def load_data():
    data = np.load('arr.npy')
    feature_names = [ 'F', 'a' ]
    feature_num = len(feature_names)
    # print(data.shape[0])
    data = data.reshape([data.shape[0] // feature_num, feature_num])
    ratio = 0.8
    offset = int(data.shape[0] * ratio)
    # 训练集和测试集的划分比例
    training_data = data[:offset]
    test_data = data[offset:]
    return training_data, test_data

Here taken as 80% of the training data set, 20% of the data sample set as

Next, we began to define the neural network, the neural network can do?

Briefly, the input to the network a value (X), by the weight, the result is the output value for the network. For Newton's second law, as will be appreciated, input acceleration a, is multiplied by a weight w, the output force F.

So how do we get the weight of it?

In general, we will weight is set to a random number, and weight training can be updated with the network in order to find the best value, so the network will be able to try to match the output target value.

How we update the weights to make it into our expectations?

Talking about this, we have to analyze, and here we actually generated by the machine weights, for example:

class Network(object):
    def __init__(self, num_of_weights):
        # 随机产生w的初始值
        # 为了保持程序每次运行结果的一致性,此处设置固定的随机数种子
        np.random.seed(0)
        self.w = np.random.randn(num_of_weights, 1)

Here Insert Picture Description
You can see, the right to the beginning of the heavy machine w is 1.77, then the acceleration is multiplied by a weight w will be a force F is 1.77, because the first acceleration value of 1, can we expect to get the force Fa is 2, here there is a gap of -0.23:
Here Insert Picture Description
error here is definitely more close to zero as possible, so we find ways to make the force F is close to the desired force Fa as much as possible, in order to change the force F, it is necessary to change the weights , but it happens, and now the weight is not what we expect minus error weights do?

I think so indeed true, as this relatively simple linear relationship in one step is very simple, in many cases, such as in cryptography function is very complex, so we have to go step by step, namely gradient descent, slowly close to the correct answer.

Here we must talked about the learning rate, people are learning step by step, the machine is the same, here we set the learning rate of 0.01:
Here Insert Picture Description
We can excel represented the relationship between them:
Here Insert Picture Description
Let's look at how to use code to make it happen:

	def update(self, x, y, eta):
        z = self.forward(x)
        gradient_w = z - y
        self.w = self.w - eta * gradient_w
        print("权重w:",self.w)

Personally think that this is the most critical step, it is recommended to try themselves on rough paper, the principle of figured it out back to see the code:

class Network(object):
    def __init__(self, num_of_weights):
        # 随机产生w的初始值
        # 为了保持程序每次运行结果的一致性,此处设置固定的随机数种子
        np.random.seed(0)
        self.w = np.random.randn(num_of_weights, 1)

    def forward(self, x):
        z = np.dot(x, self.w)
        # print("作用力F:",z)
        return z

    def loss(self, z, y):
        error = z - y
        print("error:",error)
        num_samples = error.shape[0]
        cost = error * error
        cost = np.sum(cost) / num_samples
        print("cost:",cost)
        return cost

    def update(self, x, y, eta):
        z = self.forward(x)
        gradient_w = z - y
        self.w = self.w - eta * gradient_w
        print("权重w:",self.w)

    def train(self, x, y, eta):
        z = self.forward(x)
        print("作用力F:",z)
        L = self.loss(z, y)
        self.update(x, y, eta)
        return L

Understand the principles of the code is like writing, here is the training code:

# 获取数据
train_data, test_data = load_data()
x = train_data[:, :-1]
y = train_data[:, -1:]

# 创建网络
net = Network(1)
# 启动训练
losses = []
for i in range(len(x)):
    print("加速度a:",x[i])
    print("实际作用力Fa:",y[i])
    loss = net.train(x[i],y[i], eta=0.01)
    if loss == 0:
        break
    losses.append(loss)
print(losses)

The following are the results of the training:
Here Insert Picture Description
Here Insert Picture Description
you can see, the weights slowly close to 2, will no longer grow after reaching 2:
Here Insert Picture Description
Finally draw a map look:

# 画出损失函数的变化趋势
plot_x = np.arange(len(losses))
plot_y = np.array(losses)
plt.plot(plot_x, plot_y)
plt.show()

Here Insert Picture Description
Here is all the code, you may have written bad place, welcome criticism!

import numpy as np
import matplotlib.pyplot as plt

def creat_npy():
    arr = []
    for i in range(1,1001):
        arr.append(i)
        arr.append(2 * i)
    print(arr)
    arr = np.array(arr)
    print(arr)
    np.save('arr.npy', arr)

creat_npy()

def load_data():
    data = np.load('arr.npy')
    feature_names = [ 'F', 'a' ]
    feature_num = len(feature_names)
    # print(data.shape[0])
    data = data.reshape([data.shape[0] // feature_num, feature_num])
    ratio = 0.8
    offset = int(data.shape[0] * ratio)
    # 训练集和测试集的划分比例
    training_data = data[:offset]
    test_data = data[offset:]
    return training_data, test_data

class Network(object):
    def __init__(self, num_of_weights):
        # 随机产生w的初始值
        # 为了保持程序每次运行结果的一致性,此处设置固定的随机数种子
        np.random.seed(0)
        self.w = np.random.randn(num_of_weights, 1)

    def forward(self, x):
        z = np.dot(x, self.w)
        # print("作用力F:",z)
        return z

    def loss(self, z, y):
        error = z - y
        print("error:",error)
        num_samples = error.shape[0]
        cost = error * error
        cost = np.sum(cost) / num_samples
        print("cost:",cost)
        return cost

    def update(self, x, y, eta):
        z = self.forward(x)
        gradient_w = z - y
        self.w = self.w - eta * gradient_w
        print("权重w:",self.w)

    def train(self, x, y, eta):
        z = self.forward(x)
        print("作用力F:",z)
        L = self.loss(z, y)
        self.update(x, y, eta)
        return L

# 获取数据
train_data, test_data = load_data()
x = train_data[:, :-1]
y = train_data[:, -1:]

# 创建网络
net = Network(1)
# 启动训练
losses = []
for i in range(len(x)):
    print("加速度a:",x[i])
    print("实际作用力Fa:",y[i])
    loss = net.train(x[i],y[i], eta=0.01)
    if loss == 0:
        break
    losses.append(loss)
    print(50*"-")
print(losses)

# 画出损失函数的变化趋势
plot_x = np.arange(len(losses))
plot_y = np.array(losses)
plt.plot(plot_x, plot_y)
plt.show()
Published 44 original articles · won praise 83 · views 30000 +

Guess you like

Origin blog.csdn.net/zbp_12138/article/details/104612497
Recommended