iris.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import numpy as np
  2. from sklearn import datasets
  3. iris = datasets.load_iris()
  4. dataset = [(iris.data[i][None, ...], iris.target[i]) for i in range(len(iris.target))]
  5. INPUT_DIM = 4 # входные параметры
  6. OUTPUT_DIM = 3 # ответы нейронной сети
  7. H_DIM = 5 # Количество нейронов в слое
  8. # функции
  9. def relu(x): # функция активации 1 скрытого слоя
  10. return np.maximum(0, x)
  11. def softmax(x): # функция активации выходного слоя
  12. out = np.exp(x)
  13. return out / np.sum(out)
  14. def sparse_cross_entropy(a, b): # ошибка
  15. # измерение расстояния между двумя вероятносными измерениями лучше использовать функцию кросс-энтропии
  16. # функция кросс-энтропия -Σy_i*log(z_i)
  17. return -np.log(a[0, b])
  18. def to_full(a, num_class): # правильный ответ записываем в вектор чтобы размерности совпали
  19. y_full = np.zeros((1, num_class))
  20. y_full[0, a] = 1
  21. return y_full
  22. def relu_deriv(t): # производная от функция ReLU
  23. return (t >= 0).astype(float)
  24. # два полносвязных слоя
  25. # объявление весов и bias
  26. W1 = np.random.randn(INPUT_DIM, H_DIM) # размерность (INPUT_DIM, H_DIM)
  27. b1 = np.random.randn(1, H_DIM)
  28. W2 = np.random.randn(H_DIM, OUTPUT_DIM)
  29. b2 = np.random.randn(1, OUTPUT_DIM)
  30. ALPHA = 0.01 # скорость обучения
  31. EPOCH = 200 # количество эпох
  32. loss_arr = []
  33. for epoh in range(EPOCH):
  34. for i in range(len(dataset)):
  35. x, y = dataset[i]
  36. # Forward
  37. # @ - матричное умножение
  38. t1 = x @ W1 + b1 # вычисление 1 скрытого слоя
  39. h1 = relu(t1) # функция активации промежуточного выходного слоя
  40. t2 = h1 @ W2 + b2 # вычисление 2 скрытого слоя
  41. z = softmax(t2) # функция активации выходного слоя
  42. E = sparse_cross_entropy(z, y) # ошибка
  43. # Backward
  44. y_full = to_full(y, OUTPUT_DIM) # правильный ответ записываем в ветор той же размерности что и output_dim
  45. ''' вычисление градиентов
  46. dE/dt1 <- dE/dh1 <- dE/dt2 <- E
  47. из dE/dt2 можем получить dE/dW2 и dE/db2
  48. из dE/dt1 можем получить dE/dW1 и dE/db1 '''
  49. dE_dt2 = z - y_full
  50. dE_dW2 = h1.T @ dE_dt2
  51. dE_b2 = dE_dt2
  52. dE_h1 = dE_dt2 @ W2.T
  53. dE_dt1 = dE_h1 * relu_deriv(t1)
  54. dE_dW1 = x.T @ dE_dt1
  55. dE_db1 = dE_dt1
  56. # Update
  57. W1 -= ALPHA * dE_dW1
  58. b1 -= ALPHA * dE_db1
  59. W2 -= ALPHA * dE_dW2
  60. b2 -= ALPHA * dE_b2
  61. loss_arr.append(E)
  62. def predict(x):
  63. t1 = x @ W1 + b1 # @ - матричное умножение
  64. h1 = relu(t1)
  65. t2 = h1 @ W2 + b2
  66. z = softmax(t2)
  67. return z
  68. def calc_accuracy():
  69. correct = 0
  70. for x, y in dataset:
  71. z = predict(x)
  72. y_pred = np.argmax(z)
  73. if y_pred == y:
  74. correct += 1
  75. acc = correct / len(dataset)
  76. return acc
  77. accuracy = calc_accuracy()
  78. print("Accuracy: ", accuracy)
  79. import matplotlib.pyplot as plt
  80. plt.plot(loss_arr)
  81. plt.show()
  82. x_new = [4.9, 3. , 1.4, 0.2]
  83. class_iris = ['setosa', 'versicolor', 'virginica']
  84. print(class_iris[np.argmax(predict(x_new))])