模型不够复杂
在这个例子中,首先先来看一下比较简单的线性softmax。
首先按照原来的数据进行测试,基本上是50%的正确率左右,但是稍微动一动数据有以下的变化,关键在于点集合的生成。
首先点集合的生成是由r和t来控制的,X的生成是控制三角函数的位置,如果r调整合适的话,其实X是可以成为一个很规矩的圆的。r则是半径。
对于最后的结果由集中不同的调整方式,后面的softmax的bp过程自己推一下差不多了。但是明显的就是这个模型够不上数据的分布情况。
如果生成数据变成
t = np.linspace(j*np.pi*2/3,(j+1)*np.pi*2/3,N) + np.random.randn(N)*0.2
那么我们可以看到三个区域分布着三个不同的类别,基本上是线性可分的,所以在这样的情况下,正确率90%+。
但是原来的生成方式是
t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2
这样不同的螺旋形是由重叠的。因此准确率只有50%左右。
import numpy as np
import matplotlib.pyplot as plt
N = 100;
D = 2;
K = 3;
X = np.zeros((N*K,D))
y = np.zeros(N*K,dtype = 'uint8')
for j in xrange(K):
ix = range(N*j,N*(j+1));
r = np.linspace(0,1,N);
#t = np.linspace(j*np.pi*2/3,(j+1)*np.pi*2/3,N) + np.random.randn(N)*0.2
t = np.linspace(j*4,(j+1)*4,N) + np.random.randn(N)*0.2
X[ix] = np.c_[r*np.sin(t),r*np.cos(t)]
y[ix] = j
plt.scatter(X[:,0],X[:,1],c = y,s = 40,cmap = plt.cm.Spectral)
plt.show();
W = 0.01 * np.random.randn(D,K);
b = np.zeros((1,K));
step_size = 1e-0;
reg = 1e-3;
num_examples = X.shape[0];
for i in xrange(200):
scores = np.dot(X,W)+b;
exp_scores = np.exp(scores);
probs = exp_scores / np.sum(exp_scores,axis = 1,keepdims = True);
correct_logprogs = -np.log(probs[range(num_examples),y])
data_loss = np.sum(correct_logprogs) / num_examples;
reg_loss = 0.5 * reg * np.sum(W*W);
loss = data_loss + reg_loss;
if i%10 == 0:
print("iteration %d: loss %f"%(i,loss));
dscores = probs;
dscores[range(num_examples),y] -= 1;
dscores /= num_examples;
dW = np.dot(X.T,dscores);
db = np.sum(dscores , axis = 0,keepdims = True)
dW += W * reg;
W += -step_size * dW
b += -step_size * db
scores = np.dot(X,W)+b;
predicted_class = np.argmax(scores,axis = 1);
print('training accuracy: %.2f'%(np.mean(predicted_class == y)))