<repo_name>liuyandong1988/Network<file_sep>/README.md
# Network
记录学习神经网络的过程



## 1. 全连接网络

- 神经网络的结构：
  - 激活函数；
  - 损失函数；
  - 优化器；
- 前向传播和反向传播：
  - 求损失函数的梯度；
  - 链式法则；
- 代码 一步一步搭建神经网络<file_sep>/Fully_connected/code/nn_pytorch.py
"""
使用深度学习框架完成性别判断问题
"""
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import matplotlib.pyplot as plt


class Net(nn.Module):

    def __init__(self, input_dim=2, out_put_dim=1):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(in_features=input_dim, out_features=2)
        self.fc2 = nn.Linear(in_features=2, out_features=out_put_dim)

    def forward(self, x):

        x = F.relu(self.fc1(x))
        outputs = self.fc2(x)

        return outputs

# --- 实例化一个网络 --- #
my_net = Net()
print("Network:", my_net)
# parameters
for name, params in my_net.named_parameters():
    print(name, params)
print('Total parameters:', sum(param.numel() for param in my_net.parameters()))
# --- optimizer --- #
optimizer = optim.Adam(params=my_net.parameters(), lr=0.01)

# --- data --- #
# Define dataset
data = np.array([
  [-2, -1],  # Alice
  [25, 6],   # Bob
  [17, 4],   # Charlie
  [-15, -6], # Diana
])

all_y_trues = np.array([
  1, # Alice
  0, # Bob
  0, # Charlie
  1, # Diana
])

# --- train --- #
loss_list = list()
for i in range(1000):
    # forward
    sample_index = np.random.randint(0, 4)
    x_train = data[sample_index]
    y_label = all_y_trues[sample_index]
    # numpy to tensor
    x_train = torch.tensor(x_train).to(dtype=torch.float32)
    y_label = torch.tensor(y_label).to(dtype=torch.float32).unsqueeze(dim=0)
    y_pred = my_net(x_train)
    # loss
    loss = F.mse_loss(y_pred, y_label)
    # grad zero
    optimizer.zero_grad()
    # back propagation
    loss.backward()
    # update weight
    optimizer.step()
    print('Epoch: %d Loss : %f'%(i, loss.item()))
    loss_list.append(loss.item())
plt.plot(loss_list)
plt.show()
<file_sep>/Fully_connected/code/simple_network.py
"""
简单的两层神经网络
"""

import numpy as np
from simple_neural import Neuron


# ------------------------ #
# ---     神经网络      --- #
# ------------------------ #

class OurNeuralNetwork:
    '''
    A neural network with:
      - 2 inputs
      - a hidden layer with 2 neurons (h1, h2)
      - an output layer with 1 neuron (o1)
    Each neuron has the same weights and bias:
      - w = [0, 1]
      - b = 0
    '''
    def __init__(self):
        weights = np.array([0, 1])
        bias = 0

        # The Neuron class here is from the previous section
        self.h1 = Neuron(weights, bias)
        self.h2 = Neuron(weights, bias)
        self.o1 = Neuron(weights, bias)

    def feedforward(self, x):
        out_h1 = self.h1.feedforward(x)
        out_h2 = self.h2.feedforward(x)

        # The inputs for o1 are the outputs from h1 and h2
        out_o1 = self.o1.feedforward(np.array([out_h1, out_h2]))

        return out_o1

network = OurNeuralNetwork()
x = np.array([2, 3])
print(network.feedforward(x)) # 0.721632560951842


# ------------------------ #
# ---     损失函数      --- #
# ------------------------ #
def mse_loss(y_true, y_pred):
    # y_true and y_pred are numpy arrays of the same length.
    return ((y_true - y_pred) ** 2).mean()


y_true = np.array([1, 0, 0, 1])
y_pred = np.array([0, 0, 0, 0])

print(mse_loss(y_true, y_pred)) # 0.5