fizz_buzz update

【转】:https://mathpretty.com/10526.html   

修改了模型的结构:效果显著

# @TIME : 2019/7/9 下午8:42
# @File : FizzBuzz_new.py


import numpy as np
import torch
import torch.nn as nn
import torch.utils.data as tud
from torch.autograd import Variable

# 准备数据
def binary_encode(i, num_digits):
    return np.array([i >> d & 1 for d in range(num_digits)])

def fizz_buzz_encode(i):
    if i % 15 == 0:
        return 3
    elif i % 5 == 0:
        return 2
    elif i % 3 == 0:
        return 1
    else:
        return 0
# training data -> 注意这里没有扯什么反转
NUM_DIGITS = 10  # 十个位数来表达

# 注意后面是923个数据,选择不同的batch,只会影响到最后一波剩下的个数,然后计算准确率,最后每次都会更新一次epoch的准确率
# dataloader 中已经预设了 batch,跑完一波,就计算一下
trX = np.array([binary_encode(i, NUM_DIGITS) for i in range(101, 2**NUM_DIGITS)])
trY = np.array([fizz_buzz_encode(i) for i in range(101, 2**NUM_DIGITS)])
print("trX[:5] = \n",trX[:5])
print('--------------')
print("trY[:5] = \n",trY[:5])


# 准备模型
class FizzBuzzModel(nn.Module):
    def __init__(self, in_features, out_classes, hidden_size, n_hidden_layers):
        super(FizzBuzzModel, self).__init__()

        # 注意有多层的hidden layers
        layers = []
        for i in range(n_hidden_layers):
            layers.append(nn.Linear(hidden_size, hidden_size))
            layers.append(nn.BatchNorm1d(hidden_size))
            layers.append(nn.ReLU())

        self.inputLayer = nn.Linear(in_features, hidden_size)
        self.relu = nn.ReLU()

        self.layers = nn.Sequential(*layers)

        self.outputLayer = nn.Linear(hidden_size, out_classes)

    def forward(self, x):
        x = self.inputLayer(x)
        x = self.relu(x)
        x = self.layers(x)
        out = self.outputLayer(x)
        return out


# 训练模型
# 初始化
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = FizzBuzzModel(10, 4, 150, 3).to(device)
print("model = ", model)
learning_rate = 0.02
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# DataLoader  $ 有点迷
FizzBuzzDataset = tud.TensorDataset(torch.from_numpy(trX).float().to(device),
                                    torch.from_numpy(trY).long().to(device))
dataloader = tud.DataLoader(dataset=FizzBuzzDataset, batch_size=300, shuffle=True)

# 训练
model.train()
for epoch in range(1, 300):
    for i, (batch_x, batch_y) in enumerate(dataloader):
        # print('batch_x= ', batch_x, 'shape = ', batch_x.shape)
        # print('batch_y= ', batch_y, 'shape = ', batch_y.shape)

        out = model(batch_x)
        loss = loss_fn(out, batch_y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    correct = 0
    total = 0
    # print('out.data', out.data, out.data.shape)
    _, predicted = torch.max(out.data, 1)   # 取每行中最大的概率值
    # print('predicted = ', predicted, predicted.shape)
    total += batch_y.size(0)
    correct += (predicted == batch_y).sum().item()
    acc = 100*correct/total
    print('Epoch : {:0>4d} | Loss : {:<6.4f} | Train Accuracy : {:<6.2f}%'.format(epoch,loss,acc))  #小数点后面的位数


# 模型测试
def fizz_buzz_decode(i, prediction):
    return [str(i), "fizz", "buzz", "fizzbuzz"][prediction]


# 模型预测:需要切换为 eval模式
model.eval()

testX = np.array([binary_encode(i, NUM_DIGITS) for i in range(1, 101)])
predicts = model(torch.from_numpy(testX).float().to(device))

_, res = torch.max(predicts, 1)

predictions = [fizz_buzz_decode(i, prediction) for (i, prediction) in zip(range(1, 101), res)]

print('------------------------------')
print('prediction = \n', predictions )





模型结构:

model =  FizzBuzzModel(
  (inputLayer): Linear(in_features=10, out_features=150, bias=True)
  (relu): ReLU()
  (layers): Sequential(
    (0): Linear(in_features=150, out_features=150, bias=True)
    (1): BatchNorm1d(150, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU()
    (3): Linear(in_features=150, out_features=150, bias=True)
    (4): BatchNorm1d(150, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (5): ReLU()
    (6): Linear(in_features=150, out_features=150, bias=True)
    (7): BatchNorm1d(150, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (8): ReLU()
  )
  (outputLayer): Linear(in_features=150, out_features=4, bias=True)
)

 

结果:

Epoch : 0001 | Loss : 1.7445 | Train Accuracy : 30.43 %
Epoch : 0002 | Loss : 1.2746 | Train Accuracy : 30.43 %
Epoch : 0003 | Loss : 1.2672 | Train Accuracy : 39.13 %
。。。

Epoch : 0296 | Loss : 0.7060 | Train Accuracy : 73.91 %
Epoch : 0297 | Loss : 1.5279 | Train Accuracy : 43.48 %
Epoch : 0298 | Loss : 0.6122 | Train Accuracy : 86.96 %
Epoch : 0299 | Loss : 0.0958 | Train Accuracy : 95.65 %


prediction = 
 ['1', '2', 'fizz', '4', 'buzz', 'fizz', '7', '8', 'fizz', 'buzz', '11', 'fizz', '13', '14', 'fizzbuzz', '16', '17', 'fizz', '19', 'buzz', 'fizz', '22', '23', 'fizz', 'buzz', '26', 'fizz', '28', '29', 'fizzbuzz', '31', '32', 'fizz', '34', 'buzz', 'fizz', '37', '38', 'fizz', 'buzz', '41', 'fizz', '43', '44', 'fizzbuzz', '46', '47', 'fizz', '49', 'buzz', 'fizz', '52', '53', 'fizz', 'buzz', '56', 'fizz', '58', '59', 'fizzbuzz', '61', '62', 'fizz', '64', 'buzz', 'fizz', '67', 'fizz', 'fizz', 'buzz', '71', 'fizz', '73', '74', 'fizzbuzz', '76', '77', 'fizz', '79', 'buzz', 'fizz', '82', '83', 'fizz', 'fizz', '86', 'fizz', '88', '89', 'fizzbuzz', '91', '92', 'fizz', '94', 'buzz', 'fizz', '97', '98', 'fizz', 'buzz']

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值