当前位置:   article > 正文

神经网络实现fizzbuzz小游戏_8fn.buzz

8fn.buzz

目录

一、分步骤

1、输入输出

2、模型定义

3、测试

二、总代码

1、训练阶段

2、测试阶段


FizzBuzz是一个简单的小游戏,从1开始往上数数,当遇到3的倍数的时候,说fizz,当遇到5的倍数的时候说buzz,当遇到15的倍数的时候说fizzbuzz,其他情况则正常数数。 写一个简答的小程序决定返回的是正常数值还是fizz、buzz、fizzbuzz。

一、分步骤

1、输入输出

(1)输入:

将输入数据变为10位的2进制编码(二进制编码好训练),一共可以训练1024个数,取[1,101)为测试集,[101,1024)为训练集。

需要的函数即为将输入数据变成10位二进制编码:

  1. import numpy as np
  2. num_digits=10
  3. def binary_encode(i,num_digital):
  4. return np.array([i >> d & 1 for d in range(num_digital)][::-1])#i每次循环右移d位,并和1相与,最后的编码逆序输出即可

(2)输出:

输出通常为一个数字,即可以把输出定义为:0:输出数据本身,1:输出fizz,2:输出buzz,3:输出fizzbuzz

需要定义一个将每个数字的编码函数,对真实的结果进行编码,以便和模型输出相比较

另还要定义一个解码函数,对模型的预测结果进行解码,将0,1,2,3解码为正确的数字或者英文

  1. import numpy as np
  2. import torch
  3. #先看模型输入和输出,输入是101-1024之间的数,然后对其进行二进制编码训练,所以每个输入数据的维度是10。每个数据真实输出0123这几个数(输出编码),输出维度是4,然后对输出进行解码
  4. #模型训练的是数值型的数,所以把正常数值记为0,fizz记为1,buzzj记为2,fizzbuzz记为3,对fizzbuzz进行编码,输入的数据和最后的预测值都为0123
  5. def fizzbuzz_encode(i):
  6. if i%15==0: return 3
  7. elif i%5==0: return 2
  8. elif i%3==0: return 1
  9. else :return 0
  10. #解码,对最后的预测值进行解码,将0123解码成正常数值、fizz、buzz、fizzbuzz
  11. def fizzbuzz_decode(i,prediction):
  12. return [str(i),"fizz","buzz","fizzbuzz"][prediction]

(3)测试集:

输入:输入是[101,1024)的一个tensor,并变为2进制,为923*10的tensor

真实结果:真实结果是输入的923个数据的编码,为0,1,2,3,是4维的,为923*4的tensor。应该定义为torch.LongTensor类型 ,因为编码后的是0,1,2,3的整数,一般tensor的float32类型的数据

中间隐藏层:Hidden=100(923*100)维的数据

  1. trX=torch.Tensor([binary_encode(i,num_digits) for i in range(101,2**num_digits)])
  2. trY=torch.LongTensor([fizzbuzz_encode(i) for i in range(101,2**num_digits)])

2、模型定义

  1. #模型架构
  2. model=torch.nn.Sequential(
  3. torch.nn.Linear(num_digits,Hidden,bias=False),
  4. torch.nn.ReLu(),
  5. torch.nn.Linear(Hidden,4,bias=False)
  6. )
  7. #损失函数,CrossEntropyLoss()本质是拟合/判断两种分布的相似度有多高,返回4个logits,softmax之后,可以得到个四分类的概率分布,有四种类别
  8. loss_fn=torch.nn.CrossEntropyLoss()
  9. #优化函数
  10. optimizer=torch.optim.Adam(model.parameters(),lr=0.05)
  11. #循环迭代10000次,分批次训练,每批128个数据
  12. batch_size=128
  13. for epoch in range(10000):
  14. for start in range(101,2**num_digits,batch_size)
  15. end=start+batch_size
  16. #取出本批次的batchX和batchY
  17. batchX=trX[start:end]
  18. batchY=trY[start:end]
  19. #前向传播
  20. y_pred=model(y)
  21. #loss计算
  22. loss=loss_fn(y_pred,batchY)
  23. print("Epoch",epoch,loss)
  24. #梯度清零
  25. optimizer.zero_grad()
  26. #反向传播
  27. loss.backward()
  28. #参数优化
  29. optimizer.step()

3、测试

 

  1. #定义输入和真实结果tensor
  2. testX=torch.Tensor([binary_encode(i,num_digits) for i in range(1,101)]
  3. with torch.no_grad():
  4. #结果预测及解码输出
  5. y=model(testX)
  6. prediction=zip(range(1,101),y.max(1)[1].data.tolist())
  7. print([fizzbuzz_decode(i,x) for i,x in prediction])

二、总代码

1、训练阶段

  1. import numpy as np
  2. import torch
  3. #先看模型输入和输出,输入是101-1024之间的数,然后对其进行二进制编码训练,所以每个输入数据的维度是10。每个数据真实输出0123这几个数(输出编码),输出维度是4,然后对输出进行解码
  4. #模型训练的是数值型的数,所以把正常数值记为0,fizz记为1,buzzj记为2,fizzbuzz记为3,对fizzbuzz进行编码,输入的数据和最后的预测值都为0123
  5. def fizzbuzz_encode(i):
  6. if i%15==0: return 3
  7. elif i%5==0: return 2
  8. elif i%3==0: return 1
  9. else :return 0
  10. #解码,对最后的预测值进行解码,将0123解码成正常数值、fizz、buzz、fizzbuzz
  11. def fizzbuzz_decode(i,prediction):
  12. return [str(i),"fizz","buzz","fizzbuzz"][prediction]
  13. #测试编码解码效果
  14. #for i in range(1,12):
  15. #print(fizzbuzz_decode(i,fizzbuzz_encode(i)))
  16. #定义模型的输入与输出(训练数据),本次模型使用2进制进行编码,一共训练1024个数,则需10位数表
  17. num_digits=10
  18. def binary_encode(i,num_digital):
  19. return np.array([i >> d & 1 for d in range(num_digital)][::-1])
  20. #定义输入数据,从[101,1024),x是float32输进去没问题,但y只能是0123这几个整数,类型改为LongTensor
  21. trX=torch.Tensor([binary_encode(i,num_digits) for i in range(101,2**num_digits)])
  22. trY=torch.LongTensor([fizzbuzz_encode(i) for i in range(101,2**num_digits)])
  23. #输入是923*10的矩阵,输出是923*1的矩阵,矩阵有四个数据表示,代表4
  24. num_hidden=100
  25. model=torch.nn.Sequential(
  26. torch.nn.Linear(num_digits,num_hidden,bias=False),
  27. torch.nn.ReLU (),
  28. torch.nn.Linear(num_hidden,4)
  29. )
  30. loss_fn=torch.nn.CrossEntropyLoss()#本质是拟合/判断两种分布的相似度有多高,返回4个logits,softmax之后,可以得到个四分类的概率分布,有四种类别
  31. optimizer=torch.optim.Adam(model.parameters(),lr=0.05)
  32. batch_size=128
  33. for epoch in range(10000):
  34. for start in range(101,len(trX),batch_size):
  35. end=start+batch_size
  36. batchX=trX[start:end]
  37. batchY=trY[start:end]
  38. #if torch.cuda.is_available():
  39. #batchX=batchX.cuda()
  40. #batchY=batchY.cuda()
  41. y_pred=model(batchX)
  42. loss=loss_fn(y_pred,batchY)
  43. print("epoch:",epoch,loss.item())
  44. optimizer.zero_grad()
  45. loss.backward()
  46. optimizer.step()

2、测试阶段

  1. testX=torch.Tensor([binary_encode(i,num_digits) for i in range(1,101)])
  2. with torch.no_grad():
  3. #testX是100*10的矩阵.testY是100*4的矩阵
  4. testY=model(testX)
  5. #testY是一个100*4的矩阵,在0123的每个维度上都会有一个概率输出,取概率最大的那个数据,并fizzbuzz_decode.testY.max(1)取出第一个维度上最大的那个数,但是包含两个tensor,第一个是最大的那个值,第二个是在那个位置上取到的,所以只要取出第一个tensor即可
  6. prediction=zip(range(1,101 ),testY.max(1)[1].data.tolist())
  7. print([fizzbuzz_decode(i,x) for i,x in prediction])

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/162805
推荐阅读
相关标签
  

闽ICP备14008679号