Simple binary classification

talasinski: <p>The code below solves the sklearn make_circles problem. It also provide pseudo animation of the development of the solution. For make_moons and spirals see <a href="https://github.com/talasinski/Pytorch-Neural-Net-Playground" rel="nofollow noopener">https://github.com/talasinski/Pytorch-Neural-Net-Playground</a>. Modified version of this code was used for the Boston Housing problem, see my comments to<br>
<a href="https://discuss.pytorch.org/t/pytorch-fails-to-over-fit-boston-housing-dataset/40365" class="inline-onebox">PyTorch fails to (over)fit Boston housing dataset</a></p>
<h1>original code for make_moons from</h1>
<p>#<a href="https://www.datahubbs.com/deep-learning-101-first-neural-network-with-pytorch/" rel="nofollow noopener">https://www.datahubbs.com/deep-learning-101-first-neural-network-with-pytorch/</a><br>
<span class="hashtag">#Modified</span> by Tom Lasinski for the make_circles problem and spitals.<br>
<span class="hashtag">#Also</span> added “animation” to show optimizer fitting the training data.</p>
<h1>see <a href="https://github.com/talasinski/Pytorch-Neural-Net-Playground" rel="nofollow noopener">https://github.com/talasinski/Pytorch-Neural-Net-Playground</a>
</h1>
<p>import numpy as np<br>
from sklearn.datasets import make_circles<br>
from sklearn.model_selection import train_test_split<br>
import matplotlib.pyplot as plt<br>
import torch<br>
import torch.nn as nn</p>
<p>def boundary(X): # determine boundary between different colored dots<br>
x_min, x_max = X[:, 0].min()-0.1, X[:, 0].max()+0.1<br>
y_min, y_max = X[:, 1].min()-0.1, X[:, 1].max()+0.1<br>
spacing = min(x_max - x_min, y_max - y_min) / 100<br>
XX, YY = np.meshgrid(np.arange(x_min, x_max, spacing),np.arange(y_min, y_max, spacing))<br>
data = np.hstack((XX.ravel().reshape(-1,1),YY.ravel().reshape(-1,1)))<br>
data_t = torch.FloatTensor(data)<br>
db_prob = net(data_t)<br>
clf = np.where(db_prob&lt;0.5,0,1)<br>
Z = clf.reshape(XX.shape)<br>
return(plt.contourf(XX, YY, Z, cmap=plt.cm.Accent, alpha=0.6))</p>
<p>print(“Using PyTorch Version %s” %torch.<strong>version</strong>)<br>
np.random.seed(0)<br>
torch.manual_seed(0)<br>
X, Y = make_circles(n_samples=2000, noise=0.15, factor = 0.1, random_state=1)<br>
X_train, X_test, Y_train, Y_test = train_test_split(X, Y,test_size=0.75, random_state=73)</p>
<p>fig, ax = plt.subplots(1, 2, figsize=(6,4))<br>
ax[0].set_title(‘Total Circles Data’)<br>
ax[0].scatter(X[:,0], X[:,1], c=Y)<br>
ax[1].set_title(‘Training Circles Data’)<br>
ax[1].scatter(X_train[:,0], X_train[:,1], c=Y_train)<br>
<span class="hashtag">#print</span>(’ train shape’, X_train.shape, Y_train.shape)<br>
plt.tight_layout()<br>
plt.show()</p>
<h1>Define network dimensions</h1>
<p>n_input_dim = X_train.shape[1]</p>
<h1>Layer size</h1>
<p>n_hidden2 = 40<br>
n_hidden = 20 # Number of hidden nodes<br>
n_output = 1 # Number of output nodes = for binary classifier<br>
net = nn.Sequential(<br>
nn.Linear(n_input_dim, n_hidden),<br>
nn.ELU(),<br>
nn.Linear(n_hidden, n_hidden2),<br>
nn.ELU(),<br>
nn.Linear(n_hidden2, n_output), nn.Sigmoid()<br>
)</p>
<p>loss_func = nn.BCELoss()<br>
learning_rate = 0.005<br>
optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)</p>
<p>train_loss = []<br>
train_accuracy = []<br>
iters = 300<br>
print('Shapes: ', Y_train.shape, Y_train.reshape(-1,1).shape)<br>
Y_train_t = torch.FloatTensor(Y_train).reshape(-1, 1)<br>
plot_iter = 100<br>
plot_now = 1<br>
X_train_t = torch.FloatTensor(X_train)<br>
print('Shapes: ',X_train_t.shape, Y_train_t.shape)<br>
for i in range(iters):</p>
<h1>X_train_t = torch.FloatTensor(X_train)</h1>
<pre><code>y_hat = net(X_train_t)    #this is how you make predictions.
y_hat_round = y_hat.round()

loss = loss_func(y_hat, Y_train_t)
loss.backward()
optimizer.step()
optimizer.zero_grad()
y_hat_class = np.where(y_hat.detach().numpy()&lt;0.5, 0, 1)
accuracy = np.sum(Y_train.reshape(-1,1)==y_hat_class) / len(Y_train)
train_accuracy.append(accuracy)
train_loss.append(loss.item())

if i%plot_now == 0:
	print(' Iteration: ', i, ' loss: {:.4f}'.format(loss.item()),' accuracy:', accuracy)
	y_hat_final =  y_hat_round.detach().numpy().reshape(500)
	string = 'Iteration = {}'.format(i)
	plt.figure(figsize=(5,5))
	plt.title(string)
	_ = boundary(X)
	plt.scatter(X_train [:,0], X_train [:,1], c=y_hat_final) #y_hat_class

	plt.show(block=False)
	plt.pause(0.2)
	plt.close()
	if i &gt; plot_iter : plot_now = 100
</code></pre>
<p><span class="hashtag">#summary</span> of results<br>
X_test_t = torch.FloatTensor(X_test)<br>
Y_test_t = torch.FloatTensor(Y_test).reshape(-1, 1)<br>
y_hat_test = net(X_test_t)<br>
y_hat = net(X_test_t)<br>
loss_test =loss_func(y_hat,Y_test_t)<br>
y_hat_test_class = np.where(y_hat_test.detach().numpy()&lt;0.5, 0, 1)  # torch Mickey<br>
test_accuracy = np.sum(Y_test.reshape(-1,1)==y_hat_test_class) / len(Y_test) # torch Mickey<br>
print(“Test Accuracy {:.3f}”.format(test_accuracy))<br>
print(‘Loss for Test Set: {:.4f}’.format(loss_test.item()))<br>
y_hat_round = y_hat_test.round()<br>
y_hat_final = y_hat_round.detach().numpy().reshape(1500) # torch Mickey</p>
<p>plt.figure(figsize=(12,6))<br>
plt.subplot(1,2,1)<br>
plt.title(‘Training Accuracy:{:.3f}’.format(accuracy))</p>
<p>_ = boundary(X_train)<br>
plt.scatter(X_train[:,0], X_train[:,1], c=Y_train,cmap=plt.cm.Accent)</p>
<p>plt.subplot(1,2,2)<br>
plt.title(‘Prediction Test Set: {:.3f} Loss’.format(loss_test))</p>
<p>_ = boundary(X_test)<br>
plt.scatter(X_test[:,0], X_test[:,1], c=y_hat_final,cmap=plt.cm.Accent)<br>
plt.tight_layout()<br>
plt.show()</p>