stanfordnqp / spins-b

Photonic optimization library
GNU General Public License v3.0
281 stars 110 forks source link

The use of the sigmoid function in bend90.py example. #82

Open Stevens912 opened 1 year ago

Stevens912 commented 1 year ago

I'm confused about the set command in the second picture, since we don't use the sigmoid_factor in the optimization action. We only use it in the first picture to make the design more discrete. Am I wrong? Do we use the sigmoid_factor in the scipy-minimizer? Screenshot_20230306_162332 Screenshot_20230306_162306

Stevens912 commented 1 year ago

Screenshot_20230306_163324 This is the optplan.json. As you can see, the actions only set the value of sigmoid_factor, and there is no more action for use it.

Stevens912 commented 1 year ago

In the previews spins version(invdes), the use of the function of sigmoid is very clear. The transformation of the sigmoid just behind the transformation of every continuous optimization stage.The picture is from the wdm2.py. Screenshot_20230306_175818

ludi1001 commented 1 year ago

Sigmoid factor is used to force the design to be more discrete; it's not a value that is optimized over. The purpose of set is to increase the "discreteness" of the structure in between the optimization steps.

Stevens912 commented 1 year ago

So we do a force transfomation to continuous structure after every optimization step, not every stage. Another question, from the last figure, it seems like the transformation of the sigmoid is behind the transformation of entire opt_cont. Does it illustrate that the sigmoid operation works after every stage but not every step.

ludi1001 commented 1 year ago

Sorry, by optimization step, I meant every optimization stage. sigmoid_factor.set(4) causes the overall design variable to be goos.Sigmoid(4 * (2 * design - 1)) for one round of optimization (20 optimization iterations). Then the sigmoid_factor.set(8) changes the overall design variable to be goos.Sigmoid(8 * (2 * design - 1)) and another round of optimization happens, and so forth. The two versions of code are doing roughly the same thing.

Stevens912 commented 1 year ago

Thanks a million! According to your reply, I try to compare the parametrization value before and after the sigmoid operation, the result as follows. I print the information of the two 'step.pkl' and compare the parametrization value, it seems that nothing changed. I don't know what the problem is, hope to get your help. Here's how I compare them:

with open(os.path.join("save-folder", "step35.pkl"), "rb") as fp:
      data1 = pickle.load(fp)
with open(os.path.join("save-folder", "step36.pkl"), "rb") as fp:
      data2 = pickle.load(fp)
print(data1['parametrization']['vector']==data2['parametrization']['vector'])

result: 'transformation': opt_cont0 'event': end 'time': 2023-03-09 00:56:15.366649 'log_counter': 35 'transformation': opt_cont1 'event': start 'time': 2023-03-09 00:56:16.335576 'log_counter': 36 Compare the parametrization value: [ True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True True]

The objective trajectory also doesn't increase at the point between different stages. I think it supposed to increase like mentioned in your paper. 1

Screenshot_20230310_160629

ludi1001 commented 1 year ago

The parametrization itself won't change before and after the set action because the sigmoid factor is applied on top of the parametrization, i.e. if the code had been design_new = goos.Sigmoid(sigmoid_factor * (2 * design_old - 1)), design_old (and its parametrization) won't change but you should be able to observe design_new change (if you record it).

Perhaps a better sanity check would be to just visualize the permittivity changes. While it is somewhat surprising that the optimization curve is so smooth between stages, perhaps the structure is already very discrete at the end of the first optimization stage that there's a negligible impact by the sigmoid factor change.

Stevens912 commented 1 year ago

Understood, I checked the value of objective further and it's strange that there‘s no change at all. Screenshot_20230311_183342 And I got the epsilon value by monitor, and compared the value as follows:

with open(os.path.join("save-folder", "step35.pkl"), "rb") as fp:
    data1 = pickle.load(fp)
with open(os.path.join("save-folder", "step36.pkl"), "rb") as fp:
    data2 = pickle.load(fp)
c = (data1['monitor_data']['epsilon'][2] == data2['monitor_data']['epsilon'][2])
has_false = np.any(c == False)
if has_false:
     print("There's not a False element")
else:
     print(" There's  a False element")

and it printed "There's not a False element", so the epsilon has no change at all. I‘ve ran three sets of iterations and found that they were all the same. I'm wondering what caused this and if the sigmoid factor doesn't work.