ludwig Softmax missing from Torchvision models

dy1byipe  于 10个月前  发布在  其他
关注(0)|答案(3)|浏览(101)

描述问题

我正在使用Ludwig的TorchVision模型训练一个图像分类器。
原始模型在最后一层有一个softmax操作符,但它们被移除了,因为它不属于编码器。然而,softmax层从未被放回解码器。这是有意为之吗?
我需要计算输出的softmax值。我可以向前做的3种方法有:

  • 在解码器中添加softmax层
  • 在将模型导出到Torchscript、ONNX或CoreML时添加softmax层
  • 保持原样,在应用程序中计算softmax

这里是模型架构的调试打印语句。为了简洁起见,我已经删除了大部分内容。

  1. ECD(
  2. (input_features): LudwigFeatureDict(
  3. (module_dict): ModuleDict(
  4. (image_path__ludwig): ImageInputFeature(
  5. (encoder_obj): TVEfficientNetEncoder(
  6. (model): EfficientNet(
  7. (features): Sequential(
  8. (0): Conv2dNormActivation(
  9. (0): Conv2d(3, 24, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
  10. (1): BatchNorm2d(24, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
  11. (2): SiLU(inplace=True)
  12. )
  13. // --- removed for conciseness ---
  14. (7): Conv2dNormActivation(
  15. (0): Conv2d(256, 1280, kernel_size=(1, 1), stride=(1, 1), bias=False)
  16. (1): BatchNorm2d(1280, eps=0.001, momentum=0.1, affine=True, track_running_stats=True)
  17. (2): SiLU(inplace=True)
  18. )
  19. )
  20. (avgpool): AdaptiveAvgPool2d(output_size=1)
  21. (classifier): Sequential(
  22. (0): Dropout(p=0.2, inplace=True)
  23. (1): Identity()
  24. )
  25. )
  26. )
  27. )
  28. )
  29. )
  30. (output_features): LudwigFeatureDict(
  31. (module_dict): ModuleDict(
  32. (label__ludwig): CategoryOutputFeature(
  33. (fc_stack): FCStack(
  34. (stack): ModuleList()
  35. )
  36. (reduce_sequence_input): SequenceReducer(
  37. (_reduce_obj): ReduceSum()
  38. )
  39. (decoder_obj): Classifier(
  40. (dense): Dense(
  41. (dense): Linear(in_features=1280, out_features=4, bias=True)
  42. )
  43. )
  44. (train_loss_function): SoftmaxCrossEntropyLoss(
  45. (loss_fn): CrossEntropyLoss()
  46. )
  47. )
  48. )
  49. )
  50. (combiner): ConcatCombiner(
  51. (fc_stack): FCStack(
  52. (stack): ModuleList()
  53. )
  54. )
  55. )

重现问题

Python文件:

  1. import logging
  2. from ludwig.api import LudwigModel
  3. CONFIG = "/auto-ml/ludwig.yaml"
  4. def train_classifier_ludwig(df, save_dir, model_name):
  5. model = LudwigModel(CONFIG, logging_level=logging.INFO)
  6. model.train(
  7. dataset=df,
  8. output_directory=save_dir,
  9. experiment_name="ludwig",
  10. model_name=model_name,
  11. skip_save_processed_input=True,
  12. )

YAML文件:

  1. trainer:
  2. epochs: 100
  3. early_stop: 10
  4. use_mixed_precision: false
  5. input_features:
  6. - name: image_path
  7. type: image
  8. preprocessing:
  9. num_processes: 4
  10. encoder:
  11. type: efficientnet
  12. use_pretrained: True
  13. trainable: True
  14. model_cache_dir: null
  15. model_variant: v2_m
  16. fc_layers:
  17. - output_size: 128
  18. dropout: 0.4
  19. output_features:
  20. - name: label
  21. type: category

预期行为

当对图像分类器进行推理时,输出概率之和应为1。
从具有4个类别的图像分类器获得的示例值:

  1. [-1.0383801 -1.1289184 3.9636617 -0.988309 ]

然而,应该是:

  1. [0.00659277 0.0060221 0.98045385 0.00693128]

环境

  • OS: Linux-5.15.133.1-microsoft-standard-WSL2-x86_64-with-glibc2.2
  • Python 3.10.9
  • Ludwig版本:来自master的最新版本,sha=890f261fa947ed9485065844fe1bd5a35460f6f4
    附加信息

我不确定这是否相关,但是有一个SoftmaxCrossEntropyLoss模块,但它里面没有softmax操作符。这是有意为之吗?我是不是漏掉了什么?

i2loujxw

i2loujxw1#

嘿,@saad-palapa 。编码器之后有一个组合器,然后是解码器。解码器负责添加一个最后的投影层(如果它是一个类别解码器),或者为产生预测做任何需要做的事情。
@jimthompson5802 也给我打上标签。

bsxbgnwa

bsxbgnwa2#

我没有在debug输出中看到softmax。请查看yaml文件,是否有错误?

7cjasjjr

7cjasjjr3#

Softmax实际上应用于预测模块:_CategoryPredict。
https://github.com/ludwig-ai/ludwig/blob/master/ludwig/features/category_feature.py#L100-L135
这本身并不是ECD模型的一部分,你是对的。
原因是在训练时不需要softmax,因为损失函数会应用它,而在预测时,这个模型会被用来决定是否使用校准。

相关问题