def fit(self, X_train, X_test, LA, SGS, nMB, nEpochs, epsilon, alpha, x, lambda_x, c_e, c_a, period_ovf, plots, useProb): # Initialize counter for the energies plots counter = 0 # Construct an Analyzer object analyzer = Analyzer(self.N, self.M) # Define a small validation set len_val = int(0.1 * len(X_test)) X_val = X_test[:len_val] # Standard size of the mini-batches sizeMB = int(len(X_train) / nMB) # Initialize arrays for the statistics MRE = np.zeros(nEpochs, dtype=float) nCorrect = np.zeros(nEpochs, dtype=float) sparsity = np.zeros(int(nEpochs / period_ovf), dtype=float) ovf = np.zeros((2, int(nEpochs / period_ovf)), dtype=float) # Initialize velocity velocity = np.zeros((self.N + 1, self.M + 1)) # Initialize learning parameters epsilon_0 = epsilon alpha_0 = alpha # Iterate over X_train nEpochs times for t in range(nEpochs): for ind in np.random.permutation(nMB): if ind < nMB - 1: # Create a view of the i-th mini-batch MB = X_train[ind * sizeMB:(ind + 1) * sizeMB] else: # Make a bigger mini-batch if len(X_train)%nMB != 0 MB = X_train[ind * sizeMB:] # Compute weight updates deriving from log-likelihood (heuristically) maximization and the regularization term if LA == 'CD': W_updates = epsilon * ( 1. / len(MB) * self.CD(MB, SGS, useProb) - lambda_x * self.regularize(x)) elif LA == 'PCD': W_updates = epsilon * ( 1. / len(MB) * self.PCD(MB, SGS, sizeMB, useProb) - lambda_x * self.regularize(x)) # Update the velocity velocity = W_updates + alpha * velocity #Update the weights (one time per MB) self.W += velocity # Compute and print statistics of the current epoch print("---------------Epoch {}--------------".format(t + 1)) self.GibbsSampling(X_val) MRE[t], nCorrect[t] = self.reconstructionScore(X_val, self.v) print("Mean Squared Error = ", MRE[t]) print("Correct reconstructions (%%) = %.2f \n" % nCorrect[t]) # Update the arrays for the plots if plots and (t % period_ovf == 0): # Compute the energies and the sparsity of the model ovf[:, counter] = self.monitorOverfitting(X_train[:len_val], X_val) sparsity[counter], __, __, __, T = analyzer.analyzeWeights( self.W) counter += 1 # Increase alpha and decrease epsilon while learning progresses epsilon = epsilon_0 * np.exp(-c_e * (t + 1.) / nEpochs) if alpha < 0.9: alpha = alpha_0 * np.exp(c_a * (t + 1.) / nEpochs) return MRE, nCorrect, sparsity, ovf