赞
踩
目录
FizzBuzz是一个简单的小游戏,从1开始往上数数,当遇到3的倍数的时候,说fizz,当遇到5的倍数的时候说buzz,当遇到15的倍数的时候说fizzbuzz,其他情况则正常数数。 写一个简答的小程序决定返回的是正常数值还是fizz、buzz、fizzbuzz。
(1)输入:
将输入数据变为10位的2进制编码(二进制编码好训练),一共可以训练1024个数,取[1,101)为测试集,[101,1024)为训练集。
需要的函数即为将输入数据变成10位二进制编码:
- import numpy as np
- num_digits=10
- def binary_encode(i,num_digital):
- 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解码为正确的数字或者英文
- import numpy as np
- import torch
- #先看模型输入和输出,输入是101-1024之间的数,然后对其进行二进制编码训练,所以每个输入数据的维度是10。每个数据真实输出0,1,2,3这几个数(输出编码),输出维度是4,然后对输出进行解码
- #模型训练的是数值型的数,所以把正常数值记为0,fizz记为1,buzzj记为2,fizzbuzz记为3,对fizzbuzz进行编码,输入的数据和最后的预测值都为0,1,2,3
- def fizzbuzz_encode(i):
- if i%15==0: return 3
- elif i%5==0: return 2
- elif i%3==0: return 1
- else :return 0
-
- #解码,对最后的预测值进行解码,将0,1,2,3解码成正常数值、fizz、buzz、fizzbuzz
- def fizzbuzz_decode(i,prediction):
- 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)维的数据
- trX=torch.Tensor([binary_encode(i,num_digits) for i in range(101,2**num_digits)])
- trY=torch.LongTensor([fizzbuzz_encode(i) for i in range(101,2**num_digits)])
- #模型架构
- model=torch.nn.Sequential(
- torch.nn.Linear(num_digits,Hidden,bias=False),
- torch.nn.ReLu(),
- torch.nn.Linear(Hidden,4,bias=False)
- )
- #损失函数,CrossEntropyLoss()本质是拟合/判断两种分布的相似度有多高,返回4个logits,softmax之后,可以得到个四分类的概率分布,有四种类别
- loss_fn=torch.nn.CrossEntropyLoss()
- #优化函数
- optimizer=torch.optim.Adam(model.parameters(),lr=0.05)
- #循环迭代10000次,分批次训练,每批128个数据
- batch_size=128
- for epoch in range(10000):
- for start in range(101,2**num_digits,batch_size)
- end=start+batch_size
- #取出本批次的batchX和batchY
- batchX=trX[start:end]
- batchY=trY[start:end]
- #前向传播
- y_pred=model(y)
- #loss计算
- loss=loss_fn(y_pred,batchY)
- print("Epoch",epoch,loss)
- #梯度清零
- optimizer.zero_grad()
- #反向传播
- loss.backward()
- #参数优化
- optimizer.step()
- #定义输入和真实结果tensor
- testX=torch.Tensor([binary_encode(i,num_digits) for i in range(1,101)]
- with torch.no_grad():
- #结果预测及解码输出
- y=model(testX)
- prediction=zip(range(1,101),y.max(1)[1].data.tolist())
- print([fizzbuzz_decode(i,x) for i,x in prediction])
-
-
- import numpy as np
- import torch
- #先看模型输入和输出,输入是101-1024之间的数,然后对其进行二进制编码训练,所以每个输入数据的维度是10。每个数据真实输出0,1,2,3这几个数(输出编码),输出维度是4,然后对输出进行解码
- #模型训练的是数值型的数,所以把正常数值记为0,fizz记为1,buzzj记为2,fizzbuzz记为3,对fizzbuzz进行编码,输入的数据和最后的预测值都为0,1,2,3
- def fizzbuzz_encode(i):
- if i%15==0: return 3
- elif i%5==0: return 2
- elif i%3==0: return 1
- else :return 0
-
- #解码,对最后的预测值进行解码,将0,1,2,3解码成正常数值、fizz、buzz、fizzbuzz
- def fizzbuzz_decode(i,prediction):
- return [str(i),"fizz","buzz","fizzbuzz"][prediction]
- #测试编码解码效果
- #for i in range(1,12):
- #print(fizzbuzz_decode(i,fizzbuzz_encode(i)))
-
- #定义模型的输入与输出(训练数据),本次模型使用2进制进行编码,一共训练1024个数,则需10位数表
- num_digits=10
- def binary_encode(i,num_digital):
- return np.array([i >> d & 1 for d in range(num_digital)][::-1])
- #定义输入数据,从[101,1024),x是float32输进去没问题,但y只能是0,1,2,3这几个整数,类型改为LongTensor
- trX=torch.Tensor([binary_encode(i,num_digits) for i in range(101,2**num_digits)])
- trY=torch.LongTensor([fizzbuzz_encode(i) for i in range(101,2**num_digits)])
-
- #输入是923*10的矩阵,输出是923*1的矩阵,矩阵有四个数据表示,代表4维
- num_hidden=100
- model=torch.nn.Sequential(
- torch.nn.Linear(num_digits,num_hidden,bias=False),
- torch.nn.ReLU (),
- torch.nn.Linear(num_hidden,4)
- )
- loss_fn=torch.nn.CrossEntropyLoss()#本质是拟合/判断两种分布的相似度有多高,返回4个logits,softmax之后,可以得到个四分类的概率分布,有四种类别
- optimizer=torch.optim.Adam(model.parameters(),lr=0.05)
- batch_size=128
- for epoch in range(10000):
- for start in range(101,len(trX),batch_size):
- end=start+batch_size
- batchX=trX[start:end]
- batchY=trY[start:end]
- #if torch.cuda.is_available():
- #batchX=batchX.cuda()
- #batchY=batchY.cuda()
- y_pred=model(batchX)
- loss=loss_fn(y_pred,batchY)
- print("epoch:",epoch,loss.item())
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()
- testX=torch.Tensor([binary_encode(i,num_digits) for i in range(1,101)])
- with torch.no_grad():
- #testX是100*10的矩阵.testY是100*4的矩阵
- testY=model(testX)
- #testY是一个100*4的矩阵,在0,1,2,3的每个维度上都会有一个概率输出,取概率最大的那个数据,并fizzbuzz_decode.testY.max(1)取出第一个维度上最大的那个数,但是包含两个tensor,第一个是最大的那个值,第二个是在那个位置上取到的,所以只要取出第一个tensor即可
- prediction=zip(range(1,101 ),testY.max(1)[1].data.tolist())
- print([fizzbuzz_decode(i,x) for i,x in prediction])
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。