mozhenling / dbtree

Bandit Optimization Aglorithms and Envelope Analysis based Methods for Machinery Fault Diagnosis
MIT License
13 stars 3 forks source link

function: SVMD_VKnet_torch, RuntimeError #5

Open iganggang opened 1 month ago

iganggang commented 1 month ago

Dear author, I use your svmdpy_torch.py code. However, when I run SVMD_VKnet_torch, there is an error. File "/nfsv4/23125341r/test_svmd_torch/svmdpy_torch.py", line 132, in SVMD_VKnet_torch (Alpha[n_outer]*2) (omega_axis - omega_d[:,:,n_inner]).view(-1,channel_size,signal_size)**4) + lambda_hat[n_inner,:, :,:] / 2) \ RuntimeError: The size of tensor a (336) must match the size of tensor b (7) at non-singleton dimension 1 Would you please point out where the error happens? Here is the code.

import torch
import math
import numpy as np
import torch.fft
from svmdpy_torch import SVMD_VKnet_torch

# Check if CUDA is available
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# Create a random tensor with the specified dimensions
batch = 128
input_length = 336
channel = 7
x = torch.randn(batch, input_length, channel, device=device)
print(f'Tensor is on device: {x.device}')

# Rearrange to [Batch, Channel, Input length] for SVMD processing
waveforms = x.permute(0, 2, 1)

# Set Alpha, Omega_init, Tau, and Tol
batch_size = waveforms.size(0)
channel_size = waveforms.size(1)
max_mode_num=3
max_iter_num = 500
Alpha = torch.from_numpy(np.array([1000, 1500, 100])).squeeze()  # Mode compactness
omega_init = torch.zeros(batch_size, channel_size, max_mode_num)  # Initialize frequencies to zero
tau = torch.from_numpy(np.array([0.])).float()
tol = torch.from_numpy(np.array([1e-7])).float()
device = 'cuda:0'

# Call SVMD_VKnet_torch (ensure this function is defined elsewhere)
modes, modes_fn, modes_fc, omega_axis, sum_omega_old, f_hat_plus, f_hat_negt_ = SVMD_VKnet_torch(
    waveforms, Alpha, omega_init, tau, tol, max_iter_num, max_mode_num, device
)

# Output the result
print(modes.shape)
print("Modes: ", modes)
iganggang commented 1 month ago

I find the problem comes from the channel. when I set channel=1, it works. when I set channel=2, it shows RuntimeError.

mozhenling commented 1 month ago

Dear iganggang,

Thanks a lot for pointing out the problem. I forgot to update the SVMD_VKnet_torch to accommodate multi-channel signals. You see, in the old version, there is modes_fc=modes_fc.unsqueeze(-1) # (mode_num, batch_size, channel_size, 1) in the function filter_VKnet_real_torch, which allows the broadcasting to work properly.

I have updated the codes. Please use the newest version. Thank you.

iganggang commented 1 month ago

Dear Prof Mo, Thank you for the quick response and for updating the code to handle multi-channel signals. I download and it works well with channels=3 and device='cpu' . I have a little problem with svmdpy_torch.py. You write svmdpy_torch in the torch version. Why do you use device='cpu'? Why not use GPU? It will be faster than CPU. Then I try to use it on GPU. But the program shows _RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!_ I am confused. Would you please explain it? Thanks again for your help and support!

mozhenling commented 1 month ago

Dear iganggang,

The code should work well on both GPU and CPU. Please make sure all inputs of SVMD_VKnet_torch are on the same device.

Here is an example:

import torch import math import numpy as np import torch.fft from dbtpy.filters.svmdpy_torch import SVMD_VKnet_torch

device = "cuda:0"

batch = 128 input_length = 336 channel = 7 x = torch.randn(batch, input_length, channel, device=device) print(f'Tensor is on device: {x.device}')

waveforms = x.permute(0, 2, 1)

batch_size = waveforms.size(0) channel_size = waveforms.size(1) max_mode_num=3 max_iter_num = 500 Alpha = torch.from_numpy(np.array([1000, 1500, 100])).squeeze().to(device) # Mode compactness omega_init = torch.zeros(batch_size, channel_size, max_mode_num).to(device) # Initialize frequencies to zero tau = torch.from_numpy(np.array([0.])).float().to(device) tol = torch.from_numpy(np.array([1e-7])).float().to(device)

modes, modes_fn, modes_fc, omega_axis, sum_omega_old, f_hat_plus, f_hatnegt = SVMD_VKnet_torch( waveforms, Alpha, omega_init, tau, tol, max_iter_num, max_mode_num, device )

print(modes_fc.shape) print("modes_fc: ", modes_fc)

iganggang commented 1 month ago

Thank you for the detailed explanation and the example code. I have kept all inputs to SVMD_VKnet_torch on the same device, as recommended. It works well. Thanks again for your assistance!

mozhenling commented 1 month ago

Thank you for your useful feedback.