-
Notifications
You must be signed in to change notification settings - Fork 1
Description
作者您好:
我最近在学习您的这篇论文并看了源代码,但是对于论文描述细节与代码实现我仍有一点问题。

论文图中显示的二阶段输入是由一阶段Unet生成的zernike拟合波面通过最小二乘法生成的,我很疑惑这一段在代码中的实现方式。
在文件main_lwnet.py中我观察到这一过程的实现代码如下:
for epoch in range(args['epochs_I']):
optimizer.zero_grad()
zer,wf,psf = net(max_zer)
loss = loss_MSE(zer.reshape(21), zer_init.reshape(21))
loss.backward()
optimizer.step()
这一段通过固定的初始输入拟合一阶段的Unet输出。
for epoch in tqdm(range(args['epochs_II']), leave=False):
optimizer.zero_grad()
zer,wf,psf = net(max_zer)
loss = loss_L1(psf.repeat(1, 1, 1, 1), torch.from_numpy(GT).repeat(1, 1, 1, 1))
loss.backward()
optimizer.step()
这一段与论文中相同,通过zernike系数重建psf图像进行自监督拟合。
在以上两段代码中我观察到模型输入并不是通过一阶段Unet输出的波面图计算出的zernike系数,而是通过数据集的条件筛选直接生成,这种做法与论文中的图有一些差异,请问为什么要采用这种处理方式而不是通过一阶段的波面图计算zernike系数输入。为什么在二阶段模型输出拟合psf之前先让其输出拟合一阶段的输出,请问这样设计的好处在那里。
另外我观察到二阶段输入初始化代码:
def up_limit_of_zer(zerpath,fov):
zer = pd.read_excel(zerpath, sheet_name='Sheet1', header=None, index_col=None)
info = pd.read_excel(zerpath, sheet_name='Sheet2', header=None, index_col=None)
zer = zer.drop(columns=[1, 4, 7, 9, 12, 14, 15, 17, 19, 22, 24, 26, 29, 31, 33, 35]).values
fov_info = np.expand_dims(info.iloc[:, 3].values, 1)
fov_info = np.repeat(fov_info,21,axis=1)
mask = (fov_info <= fov)
select_zer = torch.masked_select(torch.from_numpy(zer), torch.from_numpy(mask))
select_zer = select_zer.reshape(-1, 21)
max_zer,max_index = torch.max(select_zer,dim=0)
max_zer = max_zer.to(dtype=torch.float32)
max_zer = np.delete(max_zer, [4, 5, 7, 9, 12])
return max_zer.float()
在代码中
zer = zer.drop(columns=[1, 4, 7, 9, 12, 14, 15, 17, 19, 22, 24, 26, 29, 31, 33, 35]).values
表示删除16项系数为0的zernike项,与论文中表述相同。为什么在代码中
max_zer = np.delete(max_zer, [4, 5, 7, 9, 12])
多删除这五项,导致二阶段输入和输出项数不对齐。
感谢您的解答
Hello Author:
I have recently been studying this paper of yours and looking at the source code, but I still have a little problem with the details of the paper description and the code implementation.

The two-stage input shown in the paper's figure is generated by least squares from the zernike fitted wavefronts generated by Unet in the first stage, and I'm puzzled as to how this segment is implemented in the code.
In the file main_lwnet.py I observed that this process is implemented in the code as follows.
for epoch in range(args['epochs_I']):
optimizer.zero_grad()
zer,wf,psf = net(max_zer)
loss = loss_MSE(zer.reshape(21), zer_init.reshape(21))
loss.backward()
optimizer.step()
This segment fits the Unet output of one stage through a fixed initial input.
for epoch in tqdm(range(args['epochs_II']), leave=False):
optimizer.zero_grad()
zer,wf,psf = net(max_zer)
loss = loss_L1(psf.repeat(1, 1, 1, 1), torch.from_numpy(GT).repeat(1, 1, 1, 1))
loss.backward()
optimizer.step()
This segment is the same as in the paper, where the psf image is reconstructed for self-supervised fitting via zernike coefficients.
In the above two code snippets I observed that the model inputs are not zernike coefficients computed from the wavefront maps of the Unet outputs of the first stage, but are generated directly from the conditional filtering of the dataset, there are some discrepancies between this approach and the figure in the paper, may I ask why this processing is used instead of computing zernike coefficients inputs through the wavefronts of the first stage. Why is the output of the two-stage model allowed to fit the one-stage output before the output of the two-stage model is fitted to the psf, may I ask what is the benefit of this design.
Also I observed the two stage input initialization code:
def up_limit_of_zer(zerpath,fov):
zer = pd.read_excel(zerpath, sheet_name='Sheet1', header=None, index_col=None)
info = pd.read_excel(zerpath, sheet_name='Sheet2', header=None, index_col=None)
zer = zer.drop(columns=[1, 4, 7, 9, 12, 14, 15, 17, 19, 22, 24, 26, 29, 31, 33, 35]).values
fov_info = np.expand_dims(info.iloc[:, 3].values, 1)
fov_info = np.repeat(fov_info,21,axis=1)
mask = (fov_info <= fov)
select_zer = torch.masked_select(torch.from_numpy(zer), torch.from_numpy(mask))
select_zer = select_zer.reshape(-1, 21)
max_zer,max_index = torch.max(select_zer,dim=0)
max_zer = max_zer.to(dtype=torch.float32)
max_zer = np.delete(max_zer, [4, 5, 7, 9, 12])
return max_zer.float()
in these code
zer = zer.drop(columns=[1, 4, 7, 9, 12, 14, 15, 17, 19, 22, 24, 26, 29, 31, 33, 35]).values
denotes the deletion of 16 zernike terms with a coefficient of 0, as expressed in the paper. Why in the code
max_zer = np.delete(max_zer, [4, 5, 7, 9, 12])
Deleting these five more items causes the number of input and output items in the second stage to be misaligned.
Thank you for your answer!