def Try(nodeWeight, weight, printBool=False): result = [] difference = [] for i in range(1, len(nodeWeight)): if i == (len(nodeWeight) - 1): for j in range(len(nodeWeight[i])): result.append([]) difference.append([]) for k in range(len(nodeWeight[i - 1])): if k == 0: result[j] = weight[i - 1][k][j] * nodeWeight[i - 1][k] else: result[j] += weight[i - 1][k][j] * nodeWeight[i - 1][k] result[j] = sigmoid.Sigmoid(result[j]) difference[j] = (nodeWeight[-1][j] - result[j])**2 else: for j in range(len(nodeWeight[i]) - 1): for k in range(len(nodeWeight[i - 1])): #print("i=",i," j=",j," k=",k) if k == 0: nodeWeight[i][j] = weight[i - 1][k][j] * nodeWeight[i - 1][k] else: nodeWeight[i][j] += weight[i - 1][k][j] * nodeWeight[i - 1][k] nodeWeight[i][j] = sigmoid.Sigmoid(nodeWeight[i][j]) if printBool: #print("\nSuccessful Try!!!") pass return nodeWeight, result, difference
def update_filters(self, epoch): self.sigmoid_beta = 0.25 * (2**epoch) self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.sigmoid_4 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.filters = [ self.sigmoid_0, self.layering_z_1, self.max_blur_xy_2, self.layering_xy_3, self.sigmoid_4, self.scale_5 ]
def init_filters_and_variables(self): self.num_filters = 6 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.sigmoid_4 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) x_dimension_idx = 0 y_dimension_idx = 1 z_dimension_idx = 2 z_voxel_layers = self.size[2] self.layering_z_1 = layering.Layering(z_dimension_idx, self.num_z_layers) alpha = 8 self.blur_half_width = blur_half_width_voxels # # This notation is slightly confusing, but it is meant to be the # direction you blur when you are on the layer corresponding to x- # or y-layering. So, if you are layering in x, then you blur in y # and vice versa. # max_blur_x_2 = square_blur.SquareBlur(alpha, [0, self.blur_half_width, 0]) max_blur_y_2 = square_blur.SquareBlur(alpha, [self.blur_half_width, 0, 0]) self.max_blur_xy_2 = [max_blur_x_2, max_blur_y_2] single_layer = 1 layering_x_3 = layering.Layering(x_dimension_idx, single_layer) layering_y_3 = layering.Layering(y_dimension_idx, single_layer) self.layering_xy_3 = [layering_x_3, layering_y_3] scale_min = self.permittivity_bounds[0] scale_max = self.permittivity_bounds[1] self.scale_5 = scale.Scale([scale_min, scale_max]) # Initialize the filter chain self.filters = [ self.sigmoid_0, self.layering_z_1, self.max_blur_xy_2, self.layering_xy_3, self.sigmoid_4, self.scale_5 ] self.init_variables()
def update_filters(self, epoch): self.sigmoid_beta = 0.0625 * (2**epoch) self.sigmoid_2 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.filters = [ self.fourier_1d_0, self.ramp_1, self.sigmoid_2, self.scale_3 ]
def assemble_density(self, iteration): # sigmoid_strength = 2**( iteration / 25.0 ) sigmoid_strength_exp = -4.5 + int(iteration / 15.0) sigmoid_strength = 2**(sigmoid_strength_exp) sigmoid_obj = sigmoid.Sigmoid(sigmoid_strength, 0.5) device_density = np.ones( (self.opt_width_num_voxels, self.opt_vertical_num_voxels)) for profile_idx in range(0, len(self.layer_profiles)): get_start = np.sum( self.layer_thicknesses_voxels[0:profile_idx]) + np.sum( self.spacer_thicknesses_voxels[0:profile_idx]) get_profile = self.layer_profiles[profile_idx] upsampled_profile = upsample_nearest(get_profile, self.opt_width_num_voxels) if (iteration > sigmoid_start_iter) and do_sigmoid: upsampled_profile = sigmoid_obj.forward(upsampled_profile) for internal_idx in range( 0, self.layer_thicknesses_voxels[profile_idx]): device_density[:, get_start + internal_idx] = upsampled_profile return device_density
def init_filters_and_variables(self): self.num_filters = 6 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.sigmoid_2 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) x_dimension_idx = 0 y_dimension_idx = 1 z_dimension_idx = 2 alpha = 8 # I truly dislike this silent parameter passing, like truly scarily bad coding self.blur_half_width = max_blur_filter_half_width # This notation is slightly confusing, but it is meant to be the # direction you blur when you are on the layer corresponding to x- # or y-layering. So, if you are layering in x, then you blur in y # and vice versa. self.max_blur_xy_1 = square_blur.SquareBlur( alpha, [self.blur_half_width, self.blur_half_width, 0]) self.gaussian_blur_3 = GaussianBlur(gaussian_blur_filter_sigma) z_voxel_layers = self.size[2] self.layering_z_4 = layering.Layering(z_dimension_idx, self.num_z_layers, [0, 1], self.spacer_height_voxels, 0.0) scale_min = self.permittivity_bounds[0] scale_max = self.permittivity_bounds[1] self.scale_5 = scale.Scale([scale_min, scale_max]) # Initialize the filter chain self.filters = [ self.sigmoid_0, self.max_blur_xy_1, self.sigmoid_2, self.gaussian_blur_3, self.layering_z_4, self.scale_5 ] self.init_variables()
def update_filters(self, epoch): self.sigmoid_beta = 0.0625 * (2**epoch) / (2**3) # self.sigmoid_beta = 0.0625 self.layering_y_0 = layering.Layering(self.y_dimension_idx, self.num_y_layers) self.sigmoid_1 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # self.sigmoid_3 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # self.filters = [self.layering_y_0, self.sigmoid_1, self.scale_2]#[self.layering_y_0, self.scale_1]# [self.sigmoid_0, self.layering_z_1, self.max_blur_xy_2, self.sigmoid_3, self.scale_4] self.filters = [self.layering_y_0, self.sigmoid_1, self.scale_2]
def update_filters(self, epoch): self.sigmoid_beta = 0.25 * (2**epoch) z_voxel_layers = self.size[2] self.layering_z_0 = layering.Layering(self.z_dimension_idx, self.num_z_layers) self.sigmoid_1 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # self.sigmoid_3 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # self.filters = [self.layering_z_0, self.sigmoid_1, self.scale_2]#[self.layering_z_0, self.scale_1]# [self.sigmoid_0, self.layering_z_1, self.max_blur_xy_2, self.sigmoid_3, self.scale_4] self.filters = [self.scale_2]
def init_filters_and_variables(self): self.num_filters = 5 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_1 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.sigmoid_3 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) x_dimension_idx = 0 y_dimension_idx = 1 z_dimension_idx = 2 z_voxel_layers = self.size[2] self.layering_z_0 = layering.Layering(z_dimension_idx, self.num_z_layers) alpha = 12 self.blur_half_width = blur_half_width_voxels self.max_blur_xy_2 = generic_blur_2d.make_square_blur( alpha, self.blur_half_width) scale_min = self.permittivity_bounds[0] scale_max = self.permittivity_bounds[1] self.scale_4 = scale.Scale([scale_min, scale_max]) # Initialize the filter chain self.filters = [ self.layering_z_0, self.sigmoid_1, self.max_blur_xy_2, self.sigmoid_3, self.scale_4 ] self.init_variables() self.update_permittivity()
def init_filters_and_variables(self): self.num_filters = 2 #5 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.5 * 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.scale_1 = scale.Scale(self.permittivity_bounds) # Initialize the filter chain self.filters = [self.sigmoid_0, self.scale_1] self.update_filters(0) self.init_variables()
def init_filters_and_variables(self): self.num_filters = 2 #5 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # self.sigmoid_3 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) # x_dimension_idx = 0 # y_dimension_idx = 1 # z_dimension_idx = 2 # z_voxel_layers = self.size[2] # self.layering_z_0 = layering.Layering(z_dimension_idx, self.num_z_layers) # alpha = 8 # self.blur_half_width = blur_half_width_voxels # # This notation is slightly confusing, but it is meant to be the # direction you blur when you are on the layer corresponding to x- # or y-layering. So, if you are layering in x, then you blur in y # and vice versa. # # self.max_blur_xy_2 = square_blur.SquareBlur( # alpha, # [self.blur_half_width, self.blur_half_width, 0]) scale_real_min = np.real(self.permittivity_bounds[0]) scale_real_max = np.real(self.permittivity_bounds[1]) scale_real_1 = scale.Scale([scale_real_min, scale_real_max]) scale_imag_min = np.imag(self.permittivity_bounds[0]) scale_imag_max = np.imag(self.permittivity_bounds[1]) scale_imag_1 = scale.Scale([scale_imag_min, scale_imag_max]) self.scale_1 = [scale_real_1, scale_imag_1] # Initialize the filter chain self.filters = [ self.sigmoid_0, self.scale_1 ] #[self.layering_z_0, self.scale_1]# [self.sigmoid_0, self.layering_z_1, self.max_blur_xy_2, self.sigmoid_3, self.scale_4] self.init_variables()
def init_filters_and_variables(self): self.num_filters = 3 self.num_variables = 1 + self.num_filters # Start the sigmoids at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_1 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) x_dimension_idx = 0 y_dimension_idx = 1 z_dimension_idx = 2 z_voxel_layers = self.size[2] self.layering_z = layering.Layering( z_dimension_idx, self.num_z_layers, [ 0, 1 ], self.spacer_height_voxels, 0.0 ) scale_min = self.permittivity_bounds[0] scale_max = self.permittivity_bounds[1] self.scale_2 = scale.Scale([scale_min, scale_max]) self.init_variables()
def init_filters_and_variables(self): self.num_filters = 4 self.num_variables = 1 + self.num_filters self.fourier_1d_0 = Fourier1D.Fourier1D( self.size[0], self.feature_size_cutoff_voxels) self.fourier_dim = self.fourier_1d_0.fourier_dim self.ramp_1 = ramp.Ramp() # Start the sigmoid at weak strengths self.sigmoid_beta = 0.0625 self.sigmoid_eta = 0.5 self.sigmoid_2 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) scale_real_min = np.real(self.permittivity_bounds[0]) scale_real_max = np.real(self.permittivity_bounds[1]) scale_real_3 = scale.Scale([scale_real_min, scale_real_max]) scale_imag_min = np.imag(self.permittivity_bounds[0]) scale_imag_max = np.imag(self.permittivity_bounds[1]) scale_imag_3 = scale.Scale([scale_imag_min, scale_imag_max]) self.scale_3 = [scale_real_3, scale_imag_3] # Initialize the filter chain self.filters = [ self.fourier_1d_0, self.ramp_1, self.sigmoid_2, self.scale_3 ] self.update_filters(0) # # This will init the variable as complex datatype, which is good for the fourier representation # self.init_variables_(self.fourier_dim)
def __init__(self, nneurons, kinputs): self.nneurons = nneurons self.myneurons = [] for n in range(nneurons): self.myneurons.append(sg.Sigmoid(kinputs))
def update_filters(self, epoch): self.sigmoid_beta = 0.5 * 0.0625 * (2**epoch) self.sigmoid_0 = sigmoid.Sigmoid(self.sigmoid_beta, self.sigmoid_eta) self.filters = [self.sigmoid_0, self.scale_1]
def optimize( self, num_iterations, folder_for_saving ): self.fom_evolution = np.zeros( num_iterations ) self.density_prediction_evolution = np.zeros( ( num_iterations, self.design_width_voxels, self.design_height_voxels ) ) make_sigmoid = sigmoid.Sigmoid( 0.5, 2.0 ) def density_to_fields_fom_and_grad( test_density ): import_density = upsample( test_density, self.coarsen_factor ) device_permittivity = self.density_to_permittivity( import_density ) gradient_by_wl = [] fom_by_wl = [] real_fields_by_wl = [] imag_fields_by_wl = [] for wl_idx in range( 0, self.num_wavelengths ): get_focal_point_idx = self.wavelength_idx_to_focal_idx[ wl_idx ] get_fom, get_grad, get_Ez = self.compute_fom_and_gradient_and_fields( self.omega_values[ wl_idx ], device_permittivity, self.focal_spots_x_voxels[ get_focal_point_idx ], self.wavelength_intensity_scaling[ wl_idx ] ) scale_fom_for_wl = get_fom upsampled_device_grad = get_grad[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] scale_gradient_for_wl = upsampled_device_grad gradient_by_wl.append( scale_gradient_for_wl ) fom_by_wl.append( scale_fom_for_wl ) real_fields_by_wl.append( reinterpolate_average( np.real( get_Ez[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] ), self.coarsen_factor ) ) imag_fields_by_wl.append( reinterpolate_average( np.imag( get_Ez[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] ), self.coarsen_factor ) ) net_fom = np.product( fom_by_wl ) net_gradient = np.zeros( gradient_by_wl[ 0 ].shape ) # We are currently not doing a performance based weighting here, but we can add it in for wl_idx in range( 0, self.num_wavelengths ): wl_gradient = np.real( self.max_relative_permittivity - self.min_relative_permittivity ) * gradient_by_wl[ wl_idx ] weighting = net_fom / fom_by_wl[ wl_idx ] net_gradient += ( weighting * wl_gradient ) net_gradient = reinterpolate_average( net_gradient, self.coarsen_factor ) # # Now, we should zero out non-designable regions and average over designable layers # net_gradient = self.layer_spacer_averaging( net_gradient ) gradient_norm = vector_norm( net_gradient ) # Using a scaled gradient might mess up the comparison between different iterations in terms of gradient # magnitude norm_scaled_gradient = net_gradient / gradient_norm return net_fom, net_gradient, real_fields_by_wl, imag_fields_by_wl np.random.seed( 2143123 ) network_input_np = np.random.random( ( 1, 2 * self.num_wavelengths + 1, self.design_width_voxels, self.design_height_voxels ) ) - 0.5 network_input_np[ 0, 0 ] += 0.5 preinput_sigmoid = network_input_np[ 0, 0 ] network_input_np[ 0, 0 ] = make_sigmoid.forward( preinput_sigmoid )# 1.0 * np.greater_equal( network_input_np[ 0, 0 ], 0.5 ) kernel_size = 3 make_net = PermittivityPredictor( self.num_wavelengths, kernel_size ) get_density_predictions = make_net.forward( torch.tensor( network_input_np, requires_grad=True ).float() )[ 0, 0 ] preinput_sigmoid = get_density_predictions.detach().numpy() network_input_np[ 0, 0 ] = make_sigmoid.forward( preinput_sigmoid )# 1.0 * np.greater_equal( network_input_np[ 0, 0 ], 0.5 ) eval_fom, eval_grad, eval_real_fields, eval_imag_fields = density_to_fields_fom_and_grad( network_input_np[ 0, 0 ] ) for wl_idx in range( 0, self.num_wavelengths ): network_input_np[ 0, 1 + 2 * wl_idx ] = eval_real_fields[ wl_idx ] network_input_np[ 0, 1 + 2 * wl_idx + 1 ] = eval_imag_fields[ wl_idx ] optimizer = torch.optim.SGD( make_net.parameters(), lr=100.0 ) for iter_idx in range( 0, num_iterations ): if ( iter_idx % 10 ) == 0: log_file = open( self.save_folder + "/log.txt", 'a' ) log_file.write( "Iteration " + str( iter_idx ) + " out of " + str( num_iterations - 1 ) + "\n") log_file.close() sigmoid_backprop = make_sigmoid.chain_rule( -eval_grad, network_input_np[ 0, 0 ], preinput_sigmoid ) optimizer.zero_grad() loss = ( torch.tensor( sigmoid_backprop ).float() * get_density_predictions ).sum() loss.backward() optimizer.step() print( eval_fom ) # network_input_np[ 0, 0 ] = np.greater_equal( get_density_predictions.detach().numpy(), 0.5 ) # preinput_sigmoid = get_density_predictions.detach().numpy() # network_input_np[ 0, 0 ] = make_sigmoid.forward( preinput_sigmoid )# 1.0 * np.greater_equal( network_input_np[ 0, 0 ], 0.5 ) get_density_predictions = make_net.forward( torch.tensor( network_input_np, requires_grad=True ).float() )[ 0, 0 ] preinput_sigmoid = get_density_predictions.detach().numpy() network_input_np[ 0, 0 ] = make_sigmoid.forward( preinput_sigmoid )# 1.0 * np.greater_equal( network_input_np[ 0, 0 ], 0.5 ) # binarize_predictions = np.greater_equal( np.squeeze( get_density_predictions.detach().numpy() ), 0.5 ) eval_fom, eval_grad, eval_real_fields, eval_imag_fields = density_to_fields_fom_and_grad( network_input_np[ 0, 0 ] ) for wl_idx in range( 0, self.num_wavelengths ): network_input_np[ 0, 1 + 2 * wl_idx ] = eval_real_fields[ wl_idx ] network_input_np[ 0, 1 + 2 * wl_idx + 1 ] = eval_imag_fields[ wl_idx ] self.fom_evolution[ iter_idx ] = eval_fom self.density_prediction_evolution[ iter_idx ] = get_density_predictions.detach().numpy() np.save( folder_for_saving + "_fom_evolution.npy", self.fom_evolution ) np.save( folder_for_saving + "_density_prediction_evolution.npy", self.density_prediction_evolution )
def optimize_vote( self, num_iterations, folder_for_saving ): self.fom_evolution = np.zeros( num_iterations ) self.density_evolution = np.zeros( ( num_iterations, self.design_width_voxels, self.design_height_voxels ) ) make_sigmoid = sigmoid.Sigmoid( 0.5, 2.0 ) def density_to_fom_and_grad( test_density ): import_density = upsample( test_density, self.coarsen_factor ) device_permittivity = self.density_to_permittivity( import_density ) gradient_by_wl = [] fom_by_wl = [] for wl_idx in range( 0, self.num_wavelengths ): get_focal_point_idx = self.wavelength_idx_to_focal_idx[ wl_idx ] get_fom, get_grad = self.compute_fom_and_gradient( self.omega_values[ wl_idx ], device_permittivity, self.focal_spots_x_voxels[ get_focal_point_idx ], self.wavelength_intensity_scaling[ wl_idx ] ) scale_fom_for_wl = get_fom upsampled_device_grad = get_grad[ self.device_width_start : self.device_width_end, self.device_height_start : self.device_height_end ] scale_gradient_for_wl = upsampled_device_grad gradient_by_wl.append( scale_gradient_for_wl ) fom_by_wl.append( scale_fom_for_wl ) net_fom = np.product( fom_by_wl ) net_gradient = np.zeros( gradient_by_wl[ 0 ].shape ) # We are currently not doing a performance based weighting here, but we can add it in for wl_idx in range( 0, self.num_wavelengths ): wl_gradient = np.real( self.max_relative_permittivity - self.min_relative_permittivity ) * gradient_by_wl[ wl_idx ] weighting = net_fom / fom_by_wl[ wl_idx ] net_gradient += ( weighting * wl_gradient ) net_gradient = reinterpolate_average( net_gradient, self.coarsen_factor ) # # Now, we should zero out non-designable regions and average over designable layers # net_gradient = self.layer_spacer_averaging( net_gradient ) gradient_norm = vector_norm( net_gradient ) # Using a scaled gradient might mess up the comparison between different iterations in terms of gradient # magnitude norm_scaled_gradient = net_gradient / gradient_norm return net_fom, norm_scaled_gradient self.design_density = 1.0 * np.greater( np.random.random( ( self.design_width_voxels, self.design_height_voxels ) ), 0.5 ) for iter_idx in range( 0, num_iterations ): if ( iter_idx % 10 ) == 0: log_file = open( self.save_folder + "/log.txt", 'a' ) log_file.write( "Iteration " + str( iter_idx ) + " out of " + str( num_iterations - 1 ) + "\n") log_file.close() eval_fom, eval_grad = density_to_fom_and_grad( self.design_density ) print( eval_fom ) self.fom_evolution[ iter_idx ] = eval_fom self.density_evolution[ iter_idx ] = self.design_density probability_norm = 0.0 for x_idx in range( 0, self.design_width_voxels ): for y_idx in range( 0, self.design_height_voxels ): get_value = self.design_density[ x_idx, y_idx ] get_grad = eval_grad[ x_idx, y_idx ] if ( get_value > 0.5 ) and ( get_grad < 0 ): probability_norm += np.abs( get_grad ) elif ( get_value < 0.5 ) and ( get_grad > 0 ): probability_norm += np.abs( get_grad ) if probability_norm > 0: eval_grad /= ( probability_norm / 10. ) else: break for x_idx in range( 0, self.design_width_voxels ): for y_idx in range( 0, self.design_height_voxels ): get_value = self.design_density[ x_idx, y_idx ] get_grad = eval_grad[ x_idx, y_idx ] if ( get_value > 0.5 ) and ( get_grad < 0 ): if np.random.random() < np.abs( get_grad ): self.design_density[ x_idx, y_idx ] = 0.0 elif ( get_value < 0.5 ) and ( get_grad > 0 ): if np.random.random() < np.abs( get_grad ): self.design_density[ x_idx, y_idx ] = 1.0 np.save( folder_for_saving + "_fom_evolution.npy", self.fom_evolution ) np.save( folder_for_saving + "_density_evolution.npy", self.density_evolution )
def update_filters(self, epoch): self.sigmoid_beta = 0.0625 * ( 2**epoch ) self.sigmoid_1 = sigmoid.Sigmoid( self.sigmoid_beta, self.sigmoid_eta )
def update(self, gradient_real, graident_imag, gradient_real_lsf, gradient_imag_lsf, epoch, iteration): # gradient_real_interpolate = self.reinterpolate( np.squeeze( gradient_real ), [ self.opt_width_num_voxels, self.opt_vertical_num_voxels ] ) # gradient_real_interpolate = ( self.permittivity_bounds[ 1 ] - self.permittivity_bounds[ 0 ] ) * gradient_real_interpolate gradient_real_interpolate = np.squeeze(gradient_real) # import matplotlib.pyplot as plt # plt.imshow( np.squeeze( gradient_real_interpolate ) ) # plt.show() gradient_real_interpolate = 0.25 * ( gradient_real_interpolate[0:gradient_real_interpolate.shape[0] - 1, 0:gradient_real_interpolate.shape[1] - 1] + gradient_real_interpolate[1:gradient_real_interpolate.shape[0], 0:gradient_real_interpolate.shape[1] - 1] + gradient_real_interpolate[0:gradient_real_interpolate.shape[0] - 1, 1:gradient_real_interpolate.shape[1]] + gradient_real_interpolate[1:gradient_real_interpolate.shape[0], 1:gradient_real_interpolate.shape[1]]) gradient_real_interpolate = upsample_nearest_2d( gradient_real_interpolate, [self.opt_width_num_voxels, self.opt_vertical_num_voxels]) gradient_real_interpolate = ( self.permittivity_bounds[1] - self.permittivity_bounds[0]) * gradient_real_interpolate # sigmoid_strength = 2**( iteration / 25.0 ) sigmoid_strength_exp = -4.5 + int(iteration / 15.0) sigmoid_strength = 2**(sigmoid_strength_exp) sigmoid_obj = sigmoid.Sigmoid(sigmoid_strength, 0.5) max_abs_movement = 0 # avg_movement = 0 for profile_idx in range(0, len(self.layer_profiles)): get_start = np.sum( self.layer_thicknesses_voxels[0:profile_idx]) + np.sum( self.spacer_thicknesses_voxels[0:profile_idx]) get_end = get_start + self.layer_thicknesses_voxels[profile_idx] get_profile = self.layer_profiles[profile_idx] upsampled_profile = upsample_nearest(get_profile, self.opt_width_num_voxels) upsampled_profile_sig = sigmoid_obj.forward(upsampled_profile) sigmoid_grad = np.zeros( gradient_real_interpolate[:, get_start:get_end].shape) for sublayer in range(0, self.layer_thicknesses_voxels[profile_idx]): sigmoid_grad[:, sublayer] = sigmoid_obj.chain_rule( gradient_real_interpolate[:, get_start + sublayer], upsampled_profile_sig, upsampled_profile) average_gradient = np.squeeze( np.mean(gradient_real_interpolate[:, get_start:get_end], axis=1)) if (iteration > sigmoid_start_iter) and do_sigmoid: average_gradient = np.squeeze(np.mean(sigmoid_grad, axis=1)) downsampled_average_grad = downsample_average( average_gradient, len(self.layer_profiles[profile_idx])) # fig, ax = plt.subplots(constrained_layout=True) # ax.plot( downsampled_average_grad, color='g', linewidth=2 ) # secax = ax.twiny() # secax.plot( average_gradient, color='r', linewidth=2, linestyle='--' ) # plt.show() # plt.plot( average_gradient ) # plt.show() max_abs_movement = np.maximum( max_abs_movement, np.max(np.abs(downsampled_average_grad))) # avg_movement += ( 1. / len( self.layer_profiles ) ) * np.mean( np.abs( average_velocity ) ) # max_abs_movement = np.maximum( max_abs_movement, np.max( np.abs( gradient_real_interpolate[ :, get_start : get_end ] ) ) ) scaled_gradient = gradient_real_interpolate / max_abs_movement # scaled_gradient = gradient_real_interpolate / np.max( np.abs( gradient_real_interpolate ) ) scaled_step_size = 0.05 # scaled_step_size = 0.5 # scaled_step_size = 1.0 # import matplotlib.pyplot as plt # plt.imshow( np.squeeze( scaled_gradient ) ) # plt.show() for profile_idx in range(0, len(self.layer_profiles)): get_start = np.sum( self.layer_thicknesses_voxels[0:profile_idx]) + np.sum( self.spacer_thicknesses_voxels[0:profile_idx]) get_end = get_start + self.layer_thicknesses_voxels[profile_idx] upsampled_profile = upsample_nearest(get_profile, self.opt_width_num_voxels) upsampled_profile_sig = sigmoid_obj.forward(upsampled_profile) sigmoid_grad = np.zeros(scaled_gradient[:, get_start:get_end].shape) for sublayer in range(0, self.layer_thicknesses_voxels[profile_idx]): sigmoid_grad[:, sublayer] = sigmoid_obj.chain_rule( scaled_gradient[:, get_start + sublayer], upsampled_profile_sig, upsampled_profile) average_gradient = np.squeeze( np.mean(scaled_gradient[:, get_start:get_end], axis=1)) if (iteration > sigmoid_start_iter) and do_sigmoid: average_gradient = np.squeeze(np.mean(sigmoid_grad, axis=1)) get_profile = self.layer_profiles[profile_idx] downsampled_grad = downsample_average( average_gradient, len(self.layer_profiles[profile_idx])) # plt.plot( scaled_step_size * downsampled_grad ) # plt.show() get_profile -= scaled_step_size * downsampled_grad get_profile = np.minimum(1.0, np.maximum(get_profile, 0.0)) self.layer_profiles[profile_idx] = get_profile.copy()