我正在做一个项目,涉及使用Python中的smp(segmentation_models_pytorch)库进行语义分割。我正在尝试使用smp.Unet类训练一个带有辅助参数的UNet模型。但是,当我将aux_params参数添加到smp.Unet构造函数时,我遇到一个错误:
File .../python3.11/site-packages/segmentation_models_pytorch/utils/train.py:51, in Epoch.run(self, dataloader)
49 for x, y in iterator:
50 x, y = x.to(self.device), y.to(self.device)
---> 51 loss, y_pred = self.batch_update(x, y)
53 # update loss logs
54 loss_value = loss.cpu().detach().numpy()
...
-> 3162 if not (target.size() == input.size()):
3163 raise ValueError("Target size ({}) must be the same as input size ({})".format(target.size(), input.size()))
3165 return torch.binary_cross_entropy_with_logits(input, target, weight, pos_weight, reduction_enum)
File ".../train_model.py", line 153, in train
train_logs = self.train_epoch.run(self.train_loader)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../train_model.py", line 173, in main
water_seg_model.train(epoch_number=100)
File ".../train_model.py", line 176, in <module>
main()
AttributeError: 'tuple' object has no attribute 'size'
下面是我的代码的简化版本:
ENCODER = 'resnet34'
ENCODER_WEIGHTS = 'imagenet'
CLASSES = ['cats']
ACTIVATION = None
DROPOUT = 0.5
POOLING = 'avg'
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
THRESHOLD = 0.9
LEARNING_SPEED = 0.001
AUX_PARAMS = dict(
classes=len(CLASSES),
dropout=DROPOUT,
activation=ACTIVATION,
pooling=POOLING
)
class SegmentationModel():
def __init__(self):
self.model = smp.Unet(
encoder_name=ENCODER,
encoder_weights=ENCODER_WEIGHTS,
in_channels=3,
classes=len(CLASSES),
aux_params=AUX_PARAMS
)
self.preprocessing_fn = smp.encoders.get_preprocessing_fn(ENCODER, ENCODER_WEIGHTS)
self.loss = smp.losses.SoftBCEWithLogitsLoss()
self.loss.__name__ = 'SoftBCEWithLogitsLoss'
self.metrics = [
smp.utils.metrics.IoU(threshold=THRESHOLD),
]
self.optimizer = torch.optim.Adam([
dict(params=self.model.parameters(), lr=0.0001),
])
self.train_epoch = smp.utils.train.TrainEpoch(
self.model,
loss=self.loss,
metrics=self.metrics,
optimizer=self.optimizer,
device=DEVICE,
verbose=True,
)
self.dataset = Dataset(
self.images_train_dir,
self.masks_train_dir,
augmentation=get_training_augmentation(),
preprocessing=get_preprocessing(self.preprocessing_fn),
classes=['cats'],
)
self.train_loader = DataLoader(self.train_dataset, batch_size=16, shuffle=True, num_workers=6)
def train(self, epoch_number: 10):
for i in range(0, epoch_number):
print('\nEpoch: {}'.format(i))
train_logs = self.train_epoch.run(self.train_loader)
def main():
cats_seg_model = SegmentationModel()
cats_seg_model.train(epoch_number=100)
在smp.Unet中使用aux_params参数时,什么原因会导致“tuple”对象没有属性“size”错误?如何使用aux_params字典正确初始化smp.Unet模型以避免此错误?
对这个问题的任何帮助或见解将不胜感激。谢谢你,谢谢!
1条答案
按热度按时间cbeh67ev1#
来自smp docs:所有模型都支持aux_params参数,默认设置为None。如果
aux_params = None
,则不创建分类辅助输出,否则模型不仅生成掩码,还生成具有形状NC的标签输出。分类头由GlobalPooling->Dropout(可选)->Linear->Activation(可选)层组成,可以通过aux_params配置如下:因此,可能的解决方案,或者至少是变通方案,是创建一个新的Epoch类,其标签为: