FizzBuzz是一个简单的小游戏,游戏规则如下:
1)从1开始往上数数,当遇到3的倍数的时候,说fizz;
2)当遇到5的倍数,说buzz;
3)当遇到15的倍数,就说fizzbuzz;
4)其他情况下则正常数数。
现在要求使用神经网络实现FizzBuzz问题。
FizzBuzz问题本质上是一个四分类问题,即输入一个数字,我们需要将其分为数字本身、Fizz、Buzz、FizzBuzz其中的一类。我们可以搭建一个神经网络,其输入层、隐层、输出层均为全连接层,借助它完成分类任务,进而解决问题。
代码示例
1、定义转码解码函数
# 可以理解为转化为type
def fb_encode(i):
if i % 15 == 0:
return 0
elif i % 5 == 0:
return 1
elif i % 3 == 0:
return 2
else:
return 3
# 根据类型值转化
def fb_decode(i, type):
return ['fizzbuzz', 'buzz', 'fizz', str(i)][type]
# # 测试
# for i in range(1, 101):
# print(fb_decode(i, fb_encode(i)))
2、定义训练集
有了前面的转码解码函数,现在问题就转化成了4分类问题,只需要通过深度学习,找到数值和type的对应关系即可。
# 整数值转化为10位二进制列表
def to_binary(i):
bstr = str(bin(i))[2:].zfill(10)
return list(map(int, bstr))
import torch
# 1-100做测试数据,从101开始
x_train = torch.FloatTensor([to_binary(i) for i in range(101, pow(2, 10))])
y_train = torch.LongTensor([fb_encode(i) for i in range(101, pow(2, 10))]) # 分类问题,注意long类型
3、定义模型
import torch.nn as nn
D_h = 100
model = nn.Sequential(
nn.Linear(10, D_h),
nn.ReLU(D_h),
nn.Linear(D_h, 4)
)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
4、模型训练
for it in range(3000):
for batch_start in range(0, len(x_train), 64):
batch_end = batch_start + 64
x = x_train[batch_start:batch_end]
y = y_train[batch_start:batch_end]
y_hat = model(x)
loss = loss_fn(y_hat, y)
print(it, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
5、基于模型做预测
import numpy as np
x_test = torch.FloatTensor([to_binary(i) for i in range(1, 101)])
y_pred = model(x_test).max(1)[1].tolist()
# 展示真实值和预测值
for i,type in zip(range(1,101), y_pred):
print(i, fb_decode(i, fb_encode(i)), fb_decode(i, type))
# 计算准确率
np_true = np.array([fb_encode(i) for i in range(1,101)])
np_pred = np.array(y_pred)
print('ACC:', (np_true == np_pred).sum()/len(np_true))
本文为 陈华 原创,欢迎转载,但请注明出处:http://www.chenhuax.com/read/313