class ShiftModule(nn.Module): def __init__(self, input_channels, n_segment=8,n_div=8, mode='shift'): super(ShiftModule, self).__init__() self.input_channels = input_channels self.n_segment = n_segment self.fold_div = n_div self.fold = self.input_channels // self.fold_div self.conv = nn.Conv1d(self.fold_div*self.fold, self.fold_div*self.fold, kernel_size=3, padding=1, groups=self.fold_div*self.fold, bias=False) if mode == 'shift': self.conv.weight.requires_grad = True self.conv.weight.data.zero_() self.conv.weight.data[:self.fold, 0, 2] = 1 # shift left self.conv.weight.data[self.fold: 2 * self.fold, 0, 0] = 1 # shift right if 2*self.fold < self.input_channels: self.conv.weight.data[2 * self.fold:, 0, 1] = 1 # fixed elif mode == 'fixed': self.conv.weight.requires_grad = True self.conv.weight.data.zero_() self.conv.weight.data[:, 0, 1] = 1 # fixed elif mode == 'norm': self.conv.weight.requires_grad = True def forward(self, x): nt, c, h, w = x.size() n_batch = nt // self.n_segment x = x.view(n_batch, self.n_segment, c, h, w) x = x.permute(0, 3, 4, 2, 1) # (n_batch, h, w, c, n_segment) x = x.contiguous().view(n_batch*h*w, c, self.n_segment) x = self.conv(x) # (n_batch*h*w, c, n_segment) x = x.view(n_batch, h, w, c, self.n_segment) x = x.permute(0, 4, 3, 1, 2) # (n_batch, n_segment, c, h, w) x = x.contiguous().view(nt, c, h, w) return x
时间: 2023-05-20 09:01:42 浏览: 124
这是一个名为ShiftModule的类,继承自nn.Module。它有四个参数:input_channels表示输入通道数,n_segment表示分段数,默认为8,n_div表示每个分段的通道数,默认为8,mode表示模式,默认为shift。
在初始化函数__init__中,首先调用父类的构造函数,然后将参数赋值给类的属性。接着,根据n_div和fold计算出fold_div,即每个fold中的通道数。然后创建一个1D卷积层,输入通道数为fold_div*fold,输出通道数也为fold_div*fold,卷积核大小为3,padding为1,groups为fold_div*fold,表示每个fold内的通道共享卷积核,bias为False,表示不使用偏置。
如果mode为shift,则将卷积层的权重设置为可训练,初始化为0,并将第一个fold的第0个通道的第2个位置的权重设置为1。
相关问题
class DownConv(nn.Module): def __init__(self, seq_len=200, hidden_size=64, m_segments=4,k1=10,channel_reduction=16): super().__init__() """ DownConv is implemented by stacked strided convolution layers and more details can be found below. When the parameters k_1 and k_2 are determined, we can soon get m in Eq.2 of the paper. However, we are more concerned with the size of the parameter m, so we searched for a combination of parameter m and parameter k_1 (parameter k_2 can be easily calculated in this process) to find the optimal segment numbers. Args: input_tensor (torch.Tensor): the input of the attention layer Returns: output_conv (torch.Tensor): the convolutional outputs in Eq.2 of the paper """ self.m =m_segments self.k1 = k1 self.channel_reduction = channel_reduction # avoid over-parameterization middle_segment_length = seq_len/k1 k2=math.ceil(middle_segment_length/m_segments) padding = math.ceil((k2*self.m-middle_segment_length)/2.0) # pad the second convolutional layer appropriately self.conv1a = nn.Conv1d(in_channels=hidden_size, out_channels=hidden_size // self.channel_reduction, kernel_size=self.k1, stride=self.k1) self.relu1a = nn.ReLU(inplace=True) self.conv2a = nn.Conv1d(in_channels=hidden_size // self.channel_reduction, out_channels=hidden_size, kernel_size=k2, stride=k2, padding = padding) def forward(self, input_tensor): input_tensor = input_tensor.permute(0, 2, 1) x1a = self.relu1a(self.conv1a(input_tensor)) x2a = self.conv2a(x1a) if x2a.size(2) != self.m: print('size_erroe, x2a.size_{} do not equals to m_segments_{}'.format(x2a.size(2),self.m)) output_conv = x2a.permute(0, 2, 1) return output_conv
这是一个用于实现降采样卷积(DownConv)的PyTorch模型类。在构造函数中,需要指定一些参数,包括序列长度seq_len,隐藏层大小hidden_size,中间段数m_segments,卷积核大小k1和通道缩减channel_reduction。其中,降采样卷积层的实现使用了两个卷积层,第一个卷积层的卷积核大小为k1,步长为k1,将输入张量进行降采样;第二个卷积层的卷积核大小为k2,步长为k2,将第一个卷积层的输出进行进一步的降采样,并按照论文中的公式计算得到输出张量。为了使得第二个卷积层的输出张量大小与中间段数m_segments相等,需要在卷积层中进行适当的padding。在前向传播时,需要将输入张量进行维度变换,使得其可以被卷积层处理,然后将卷积层的输出张量再次进行维度变换,使得其可以作为下一层的输入。如果第二个卷积层的输出张量大小不等于中间段数m_segments,则会输出一条错误信息。
CHUNK = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 2 RATE = 44100 RECORED_SECONDS = 0.5 TERMINATE = False def run(self): p = pyaudio.PyAudio() while True: try: self.sock.connect(self.ADDR) break except: time.sleep(3) continue print('音频客户端已经连接...') self.stream = self.p.open(format = FORMAT, channels=CHANNELS, rate=RATE, input=True, frames_per_buffer=CHUNK) while self.stream.is_active(): frames = [] for i in range(0,int(RATE / CHUNK * RECORED_SECONDS)): data = self.stream.read(CHUNK) frames.append(data) # 将音频数据转换为PyDub的音频片段 audio_segment = AudioSegment( data=b''.join(frames), sample_width=p.get_sample_size(FORMAT), frame_rate=RATE, channels=CHANNELS ) # 变声 audio_segment = audio_segment.speedup( playback_speed=SPEEDUP_FACTOR, chunk_size=CHUNK, crossfade=10 修改上述代码,实现变音功能
要实现变音功能,可以使用 PyDub 库中的 `pitch_shift` 方法。在上述代码中,可以在 `audio_segment` 变量上调用该方法,例如:
```
# 变声
audio_segment = audio_segment.speedup(
playback_speed=SPEEDUP_FACTOR,
chunk_size=CHUNK,
crossfade=10
)
# 变音
audio_segment = audio_segment.pitch_shift(
semitones=SHIFT_SEMITONES
)
```
其中,`SHIFT_SEMITONES` 是需要变化的半音数,可以是正数或负数,例如 `SHIFT_SEMITONES = 2` 表示将音高升高两个半音。
阅读全文