You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

regression.py 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import numpy as np
  2. np.random.seed(42)
  3. import time
  4. import os
  5. import matplotlib.pyplot as plt
  6. import uctc.nn as nn
  7. from utils import parameter_data, Dataset
  8. use_graphics = False
  9. class RegressionModel(object):
  10. """
  11. A neural network model for approximating a function that maps from real
  12. numbers to real numbers. The network should be sufficiently large to be able
  13. to approximate sin(x) on the interval [-2pi, 2pi] to reasonable precision.
  14. """
  15. def __init__(self):
  16. # Initialize your model parameters here
  17. self.batch_size = 10
  18. self.input_features = 1
  19. self.output_features = 1
  20. self.hidden_f1 = 50
  21. self.lr = 0.01
  22. self.w1 = nn.Parameter(parameter_data(self.input_features, self.hidden_f1))
  23. self.b1 = nn.Parameter(parameter_data(1, self.hidden_f1))
  24. self.w2 = nn.Parameter(parameter_data(self.hidden_f1, self.output_features))
  25. self.b2 = nn.Parameter(parameter_data(1, self.output_features))
  26. def run(self, x):
  27. """
  28. Runs the model for a batch of examples.
  29. Inputs:
  30. x: a node with shape (batch_size x 1)
  31. Returns:
  32. A node with shape (batch_size x 1) containing predicted y-values
  33. """
  34. "*** YOUR CODE HERE ***"
  35. # uctc
  36. linear1 = nn.Linear(x, self.w1)
  37. bias1 = nn.AddBias(linear1, self.b1)
  38. act1 = nn.ReLU(bias1)
  39. linear2 = nn.Linear(act1, self.w2)
  40. bias2 = nn.AddBias(linear2, self.b2)
  41. # numpy
  42. # print(len(x.data()))
  43. _x = np.array(x.data()).reshape(-1, 1)
  44. _w1 = np.array(self.w1.data()).reshape(self.input_features, -1)
  45. _b1 = np.array(self.b1.data()).reshape(1, -1)
  46. _w2 = np.array(self.w2.data()).reshape(self.hidden_f1, -1)
  47. _b2 = np.array(self.b2.data()).reshape(1, -1)
  48. _linear1 = np.dot(_x, _w1) + _b1
  49. _act1 = np.maximum(0.0, _linear1)
  50. _linear2 = np.dot(_act1, _w2) + _b2
  51. return bias2
  52. def get_loss(self, x, y):
  53. """
  54. Computes the loss for a batch of examples.
  55. Inputs:
  56. x: a node with shape (batch_size x 1)
  57. y: a node with shape (batch_size x 1), containing the true y-values
  58. to be used for training
  59. Returns: a loss node
  60. """
  61. "*** YOUR CODE HERE ***"
  62. predict_y = self.run(x)
  63. return nn.SquareLoss(predict_y, y)
  64. def train(self, dataset):
  65. """
  66. Trains the model.
  67. """
  68. "*** YOUR CODE HERE ***"
  69. itera = 0
  70. while True:
  71. for x, y in dataset.iterate_once(self.batch_size):
  72. loss = self.get_loss(x, y)
  73. g_w1, g_b1, g_w2, g_b2 = nn.gradients(loss, [self.w1, self.b1, self.w2, self.b2])
  74. self.w1.update(g_w1, self.lr)
  75. self.b1.update(g_b1, self.lr)
  76. self.w2.update(g_w2, self.lr)
  77. self.b2.update(g_b2, self.lr)
  78. itera += 1
  79. if loss.data()[0] < 0.01:
  80. break
  81. class RegressionDataset(Dataset):
  82. def __init__(self, model: RegressionModel):
  83. x = np.expand_dims(np.linspace(-2 * np.pi, 2 * np.pi, num=200), axis=1)
  84. np.random.RandomState(0).shuffle(x)
  85. self.argsort_x = np.argsort(x.flatten())
  86. y = np.sin(x)
  87. super().__init__(x, y)
  88. self.model = model
  89. self.processed = 0
  90. if use_graphics:
  91. fig, ax = plt.subplots(1, 1)
  92. ax.set_xlim(-2 * np.pi, 2 * np.pi)
  93. ax.set_ylim(-1.4, 1.4)
  94. real, = ax.plot(x[self.argsort_x], y[self.argsort_x], color="blue")
  95. learned, = ax.plot([], [], color="red")
  96. text = ax.text(0.03, 0.97, "", transform=ax.transAxes, va="top")
  97. ax.legend([real, learned], ["real", "learned"])
  98. plt.show(block=False)
  99. self.fig = fig
  100. self.learned = learned
  101. self.text = text
  102. self.last_update = time.time()
  103. def iterate_once(self, batch_size):
  104. for x, y in super().iterate_once(batch_size):
  105. yield x, y
  106. self.processed += batch_size
  107. if time.time() - self.last_update > 0.01:
  108. predicted = self.model.run(nn.Constant(self.x)).data()
  109. loss = self.model.get_loss(
  110. x, y).data()
  111. predicted = np.array(predicted)
  112. loss = loss[0]
  113. print(f"processed: {self.processed}\nloss: {loss: .6f}")
  114. if use_graphics:
  115. self.learned.set_data(self.x[self.argsort_x], predicted[self.argsort_x])
  116. self.text.set_text(f"processed: {self.processed}\nloss: {loss: .6f}")
  117. self.fig.canvas.draw_idle()
  118. self.fig.canvas.start_event_loop(1e-3)
  119. self.last_update = time.time()
  120. model = RegressionModel()
  121. dataset = RegressionDataset(model)
  122. model.train(dataset)