Transformers documentation
Ses Spektrogram Dönüşümü
Bu model 2021-04-05 tarihinde HF papers'ta yayımlandı ve 2022-11-21 tarihinde Hugging Face Transformers'a katkıda bulunuldu.
Ses Spektrogram Dönüşümü
Genel Bakış
Audio Spectrogram Transformer modeli, Yuan Gong, Yu-An Chung ve James Glass tarafından AST: Audio Spectrogram Transformer makalesinde önerilmiştir. Audio Spectrogram Transformer, sesi bir görüntüye (spektrogram) dönüştürerek Vision Transformer'ı ses verisine uygular. Model, ses sınıflandırma için en iyi sonuçları elde eder.
Makalenin özeti aşağıdaki gibidir:
Geçen on yıl boyunca, konvolüsyonel sinir ağları (CNN'ler), ses spektrogramlarından ilgili etiketlere doğrudan bir eşleme öğrenmeyi amaçlayan uçtan uca ses sınıflandırma modellerinin ana yapı taşı olarak yaygın şekilde benimsenmiştir. Uzun menzilli küresel bağlamı daha iyi yakalamak için son zamanlardaki bir eğilim, CNN'nin üzerine bir öz-dikkat mekanizması ekleyerek CNN-dikkat hibrit modeli oluşturmaktır. Ancak, CNN'ye bağımlılığın gerekli olup olmadığı ve saf olarak dikkate dayalı sinir ağlarının ses sınıflandırmada iyi performans elde etmek için yeterli olup olmadığı belirsizdir. Bu makalede, soruyu Audio Spectrogram Transformer (AST) ile yanıtlandırıyoruz; AST, ses sınıflandırma için ilk konvolüsyonsuz, saf olarak dikkate dayalı modeldir. AST'yi çeşitli ses sınıflandırma kıstaslarında değerlendiriyoruz; model, AudioSet'te 0,485 mAP, ESC-50'de %95,6 ve Speech Commands V2'de %98,1 doğruluk oranlarıyla yeni en iyi sonuçları elde etmektedir.
Audio Spectrogram Transformer architecture. Taken from the original paper. Bu model nielsr tarafından katkıda bulunmuştur. Orijinal kod burada bulunabilir.
Kullanım ipuçları
- Kendi veri setinizde Audio Spectrogram Transformer (AST) modelini ince ayar yaparken, girdi normalizasyonunu (girdinin 0 ortalamaya ve 0.5 standart sapmaya sahip olduğundan emin olmak için) sizin yapmanız önerilir. ASTFeatureExtractor bu işlemden sorumludur. Not: Varsayılan olarak AudioSet ortalama ve standart sapma değerlerini kullanır. Yazarların bir alt akış (downstream) veri seti için istatistikleri nasıl hesapladığını görmek için
ast/src/get_norm_stats.pydosyasını inceleyebilirsiniz. - AST'nin düşük bir öğrenme hızına ihtiyaç duyduğunu unutmayın (yazarlar, PSLA makalesinde önerdikleri CNN modeline kıyasla 10 kat daha küçük bir öğrenme hızı kullanıyor) ve hızlı bir şekilde yakınsıyor; bu nedenle lütfen göreviniz için uygun bir öğrenme hızı ve öğrenme hızı zamanlayıcısı arayın.
Ölçekli Nokta Çarpımı Dikkat (SDPA) Kullanımı
PyTorch, torch.nn.functional parçası olarak yerel ölçekli nokta çarpımı dikkati (SDPA) operatörünü içerir. Bu fonksiyon, girdilere ve kullanılan donanıma bağlı olarak uygulanabilecek çeşitli uygulamaları kapsar. Daha fazla bilgi için resmi dokümantasyonu veya GPU Inference sayfasına bakın.
torch>=2.1.1 için bir uygulama mevcut olduğunda varsayılan olarak SDPA kullanılır, ancak SDPA'nın kullanılmasını açıkça istemek için from_pretrained() içinde attn_implementation="sdpa" ayarlayabilirsiniz.
from transformers import ASTForAudioClassification
model = ASTForAudioClassification.from_pretrained("MIT/ast-finetuned-audioset-10-10-0.4593", attn_implementation="sdpa", device_map="auto")
...En iyi hızlanmalar için, modelin yarım hassasiyette (ör. torch.float16 veya torch.bfloat16) yüklenmesini öneririz.
Yerel bir benchmark'ta (A100-40GB, PyTorch 2.3.0, OS Ubuntu 22.04) float32 ve MIT/ast-finetuned-audioset-10-10-0.4593 modeliyle, çıkarım sırasında aşağıdaki hızlanmaları gözlemledik.
| Toplu işlem boyutu | Ortalama çıkarım süresi (ms), aceleci mod | Ortalama çıkarım süresi (ms), sdpa modeli | Hızlandırma, Sdpa / Eager (x) |
|---|---|---|---|
| 1 | 27 | 6 | 4.5 |
| 2 | 12 | 6 | 2 |
| 4 | 21 | 8 | 2.62 |
| 8 | 40 | 14 | 2.86 |
Kaynaklar
Audio Spectrogram Transformer ile başlamanıza yardımcı olmak için resmi Hugging Face ve topluluk (🌎 ile belirtilen) kaynaklarının listesi.
- Ses sınıflandırma için AST ile çıkarımın gösterildiği bir defter burada bulunabilir.
- Bu notebook ASTForAudioClassification sınıfını destekler.
- Bkz: Ses sınıflandırma.
Buraya bir kaynak eklemek isterseniz, bir Pull Request açmaktan çekinmeyin; inceleyeceğiz! Kaynağın, mevcut bir kaynağı tekrarlamak yerine ideal olarak yeni bir şeyi göstermesi beklenir.
ASTConfig
sınıf transformers.ASTConfig
< source >( transformers_version: str | None = Nonearchitectures: list[str] | None = Noneoutput_hidden_states: bool | None = Falsereturn_dict: bool | None = Truedtype: str | torch.dtype | None = Nonechunk_size_feed_forward: int = 0is_encoder_decoder: bool = Falseid2label: dict[int, str] | dict[str, str] | None = Nonelabel2id: dict[str, int] | dict[str, str] | None = Noneproblem_type: Literal['regression', 'single_label_classification', 'multi_label_classification'] | None = Nonehidden_size: int = 768num_hidden_layers: int = 12num_attention_heads: int = 12intermediate_size: int = 3072hidden_act: str = 'gelu'hidden_dropout_prob: float | int = 0.0attention_probs_dropout_prob: float | int = 0.0initializer_range: float = 0.02layer_norm_eps: float = 1e-12patch_size: int | list[int] | tuple[int, int] = 16qkv_bias: bool = Truefrequency_stride: int = 10time_stride: int = 10max_length: int = 1024num_mel_bins: int = 128 )
Parametreler
- hidden_size (
int, isteğe bağlı, varsayılan768) — Gizli temsillerin boyutu. - num_hidden_layers (
int, isteğe bağlı, varsayılan12) — Transformer çözücüdeki gizli katman sayısı. - num_attention_heads (
int, isteğe bağlı, varsayılan12) — Transformer decoder'ındaki her dikkat katmanı için dikkat başı sayısı. - intermediate_size (
int, isteğe bağlı, varsayılan3072) — MLP temsillerinin boyutu. - hidden_act (
str, isteğe bağlı, varsayılangelu) — Çözücüdeki doğrusal olmayan aktivasyon fonksiyonu (fonksiyon veya dize). Örneğin,"gelu","relu","silu"vb. - hidden_dropout_prob (
Union[float, int], isteğe bağlı, varsayılan0.0) — Gömme, kodlayıcı ve havuzlayıcıdaki tüm tam bağlı katmanlar için dropout olasılığı. - attention_probs_dropout_prob (
Union[float, int], isteğe bağlı, varsayılan0.0) — Dikkat olasılıkları için dropout oranı. - initializer_range (
float, isteğe bağlı, varsayılan0.02) — Tüm ağırlık matrislerini başlatmak için kullanılan truncated_normal_initializer'ın standart sapması. - layer_norm_eps (
float, isteğe bağlı, varsayılan1e-12) — Katman normalizasyon katmanları tarafından kullanılan epsilon. - patch_size (
Union[int, list[int], tuple[int, int]], isteğe bağlı, varsayılan16) — Her yamanın boyutu (çözünürlüğü). - qkv_bias (
bool, isteğe bağlı, varsayılanTrue) — Sorgulara, anahtarlara ve değerlere bir sapma eklenip eklenmeyeceği. - frequency_stride (
int, isteğe bağlı, varsayılan 10) — Spektrogramları yama (patch) haline getirirken kullanılacak frekans adımı. - time_stride (
int, isteğe bağlı, varsayılan 10) — Spektrogramları yama (patch) haline getirirken kullanılacak zamansal atlama (stride). - max_length (
int, isteğe bağlı, varsayılan 1024) — Spektrogramların zaman boyutu. - num_mel_bins (
int, isteğe bağlı, varsayılan128) — Giriş başına kullanılan mel özellik sayısı.AutoFeatureExtractorsınıfında kullanılan değerle eşleşmelidir.
Bu, bir Audio Spectrogram TransformerModel yapılandırmasını depolamak için kullanılan yapılandırma sınıfıdır. Belirtilen argümanlara göre bir Audio Spectrogram Transformer modeli örneklemek ve model mimarisini tanımlamak için kullanılır. Varsayılan değerlerle bir yapılandırma örneği oluşturmak, MIT/ast-finetuned-audioset-10-10-0.4593 modelinin yapılandırmasına benzer bir yapılandırma üretir.
Yapılandırma nesneleri PreTrainedConfig sınıfından devralır ve model çıktılarını kontrol etmek için kullanılabilir. Daha fazla bilgi için PreTrainedConfig belgesini okuyun.
Örnek:
>>> from transformers import ASTConfig, ASTModel
>>> # Initializing a AST MIT/ast-finetuned-audioset-10-10-0.4593 style configuration
>>> configuration = ASTConfig()
>>> # Initializing a model (with random weights) from the MIT/ast-finetuned-audioset-10-10-0.4593 style configuration
>>> model = ASTModel(configuration)
>>> # Accessing the model configuration
>>> configuration = model.configASTFeatureExtractor
sınıf transformers.ASTFeatureExtractor
< source >( feature_size = 1sampling_rate = 16000num_mel_bins = 128max_length = 1024padding_value = 0.0do_normalize = Truemean = -4.2677393std = 4.5689974return_attention_mask = False**kwargs )
Parametreler
- feature_size (
int, isteğe bağlı, varsayılan 1) — Çıkarılan özelliklerin boyutu. - sampling_rate (
int, isteğe bağlı, varsayılan 16000) — Ses dosyalarının dijitalleştirilmesi gereken örnekleme hızı, hertz (Hz) cinsinden ifade edilir. - num_mel_bins (
int, isteğe bağlı, varsayılan 128) — Mel frekans kutu sayısı. - max_length (
int, isteğe bağlı, varsayılan 1024) — Çıkarılan özelliklerin doldurulacağı/kısaltılacağı maksimum uzunluk. - do_normalize (
bool, isteğe bağlı, varsayılanTrue) —meanvestdkullanılarak log-Mel özelliklerinin normalize edip edilmeyeceği. - mean (
float, isteğe bağlı, varsayılan -4.2677393) — Log-Mel özelliklerini normalize etmek için kullanılan ortalama değer. Varsayılan olarak AudioSet ortalamasını kullanır. - std (
float, isteğe bağlı, varsayılan 4.5689974) — Log-Mel özelliklerini normalize etmek için kullanılan standart sapma değeri. Varsayılan olarak AudioSet standart sapmasını kullanır. - return_attention_mask (
bool, isteğe bağlı, varsayılanFalse) — call()attention_maskdöndürmeli mi?
Bir Audio Spectrogram Transformer (AST) özellik çıkarıcısı oluşturur.
Bu özellik çıkarıcı, ana yöntemlerin çoğunu içeren SequenceFeatureExtractor sınıfından devralır. Kullanıcıların bu yöntemler hakkında daha fazla bilgi için bu üst sınıfa başvurması gerekir.
Bu sınıf, yüklüyse TorchAudio, değilse numpy kullanarak ham ses verisinden mel-filtre bankası özelliklerini çıkarır, bunları sabit bir uzunluğa kısaltır/uzatır ve ortalama ile standart sapma kullanarak normalize eder.
__call__
< source >( raw_speech: numpy.ndarray | list[float] | list[numpy.ndarray] | list[list[float]]sampling_rate: int | None = Nonereturn_tensors: str | transformers.utils.generic.TensorType | None = None**kwargs )
Parametreler
- raw_speech (
np.ndarray,list[float],list[np.ndarray],list[list[float]]) — Doldurulacak (padding) dizi veya dizi grubu. Her dizi, bir numpy dizisi, bir float değerleri listesi, bir numpy dizileri listesi veya float değerleri listeleri listesi olabilir. Tek kanallı (mono) ses olmalı, stereo değil; yani her zaman adımı için tek bir float değer içermelidir. - sampling_rate (
int, isteğe bağlı) —raw_speechgirdisinin örneklenmiş olduğu örneklem hızı. Sessiz hataları önlemek için ileri çağrıdasampling_ratedeğerinin geçirilmesi şiddetle önerilir. - return_tensors (
strveya TensorType, isteğe bağlı) — Belirlenirse, Python tamsayı listesi yerine tensörler döndürülür. Kabul edilen değerler şunlardır:'pt': PyTorchtorch.Tensornesnelerini döndürür.'np': Numpynp.ndarraynesnelerini döndürür.
Bir veya birden fazla diziyi model için özelliklendirmek ve hazırlamak için ana yöntem.
ASTModel
sınıf transformers.ASTModel
< source >( config: ASTConfig )
Parametreler
- config (ASTConfig) — Modelin tüm parametrelerini içeren model yapılandırma sınıfı. Bir yapılandırma dosyasıyla başlatmak, modelle ilişkili ağırlıkları yüklemez, yalnızca yapılandırmayı yükler. Model ağırlıklarını yüklemek için from_pretrained() yöntemine bakın.
Üzerinde herhangi bir özel başlık olmadan ham gizli durumlar (hidden-states) üreten çıplak Audio Spectrogram Transformer Model.
Bu model PreTrainedModel sınıfından devralır. Kütüphanenin tüm modelleri için uyguladığı genel yöntemler (indirme veya kaydetme, giriş gömme boyutlarını yeniden boyutlandırma, başları budama vb.) için üst sınıf belgelendirmesine bakın.
Bu model aynı zamanda bir PyTorch torch.nn.Module alt sınıfıdır. Bunu standart bir PyTorch Module olarak kullanın ve genel kullanım ve davranışla ilgili tüm konular için PyTorch dokümantasyonuna başvurun.
forward
< source >( input_values: typing.Optional[torch.Tensor] = Noneattention_mask: typing.Optional[torch.Tensor] = None**kwargs: *<class 'transformers.utils.generic.TransformersKwargs'> ) → BaseModelOutputWithPooling or tuple(torch.Tensor)
Parametreler
- input_values (
torch.Tensor, şekli(batch_size, max_length, num_mel_bins)) — Ham ses dalgasından çıkarılan mel özelliklerinin kayan nokta değerleri. Ham ses dalgası, bir.flacveya.wavses dosyasınılist[float]tipinde bir diziye,numpy.ndarrayveyatorch.Tensortipine yükleyerek elde edilebilir; örneğin torchcodec kütüphanesi (pip install torchcodec) veya soundfile kütüphanesi (pip install soundfile) aracılığıyla. Diziyiinput_featuresiçin hazırlamak için, mel özelliklerini çıkarmak, dolgu yapmak vetorch.Tensortipinde bir tensöre dönüştürmek üzere AutoFeatureExtractor kullanılmalıdır. Bkz. call() - attention_mask (
torch.Tensorşeklinde(batch_size, sequence_length), isteğe bağlı) — Doldurma (padding) token indekslerinde dikkat (attention) işlemi yapmaktan kaçınmak için kullanılan maske. Seçilen maske değerleri[0, 1]:- 1, maskelenmemiş jetonlar için,
- maskelenmiş jetonlar için 0.
Dönüş değeri
BaseModelOutputWithPooling veya tuple(torch.Tensor)
A BaseModelOutputWithPooling veya bir torch.Tensor demeti (eğer return_dict=False geçirildiyse veya config.return_dict=False ise), yapılandırmaya (ASTConfig) ve girdilere bağlı olarak çeşitli öğelerden oluşur.
ASTModel forward metodu, __call__ özel metodunu geçersiz kılar.
İleri geçiş tarifi bu fonksiyon içinde tanımlanmalı olsa da, sonrasında bunun yerine
Moduleörneğini çağırmak gerekir; çünkü önceki, ön ve son işleme adımlarını çalıştırmaktan sorumluyken ikincisi bunları sessizce yok sayar.
last_hidden_state (
torch.Tensor, şekli(batch_size, sequence_length, hidden_size)) — Modelin son katmanının çıktısındaki gizli durumlar dizisi.pooler_output (
torch.Tensor, şekli(batch_size, hidden_size)) — Sıranın ilk token'ının (sınıflandırma token'ı) son katman gizli durumu, yardımcı ön eğitim görevi için kullanılan katmanlar üzerinden ek işlemden geçirildikten sonraki hali. Örneğin BERT ailesi modelleri için, bu, sınıflandırma token'ının doğrusal bir katman ve tanh aktivasyon fonksiyonu üzerinden işlenmesinden sonra döndürülen değerdir. Doğrusal katman ağırlıkları, ön eğitim sırasında bir sonraki cümle tahmini (sınıflandırma) hedefinden eğitilir.hidden_states (
tuple(torch.Tensor), isteğe bağlı,output_hidden_states=Truegeçirildiğinde veyaconfig.output_hidden_states=Trueolduğunda döndürülür) —torch.Tensor(modelin bir gömme katmanı varsa gömme katmanının çıktısı için bir tane + her katmanın çıktısı için birer tane) içeren,(batch_size, sequence_length, hidden_size)biçiminde bir demet.Her katmanın çıktısında modelin gizli durumları ve isteğe bağlı başlangıç gömme çıktıları.
attentions (
tuple(torch.Tensor), isteğe bağlı,output_attentions=Truegeçirildiğinde veyaconfig.output_attentions=Trueolduğunda döndürülür) —torch.Tensor(katman başına bir tane) içeren bir tuple, şekli(batch_size, num_heads, sequence_length, sequence_length).Dikkat softmax'ı sonrası dikkat ağırlıkları, öz-dikkat başlıklarında ağırlıklı ortalamanın hesaplanmasında kullanılır.
ASTForAudioClassification
sınıf transformers.ASTForAudioClassification
< source >( config: ASTConfig )
Parametreler
- config (ASTConfig) — Modelin tüm parametrelerini içeren model yapılandırma sınıfı. Bir yapılandırma dosyasıyla başlatmak, modelle ilişkili ağırlıkları yüklemez, yalnızca yapılandırmayı yükler. Model ağırlıklarını yüklemek için from_pretrained() yöntemine bakın.
Üstünde bir ses sınıflandırma başlığı (toplanmış çıktının üzerinde doğrusal bir katman) bulunan Audio Spectrogram Transformer modeli, örneğin AudioSet, Speech Commands v2 gibi veri setleri için.
Bu model PreTrainedModel sınıfından devralır. Kütüphanenin tüm modelleri için uyguladığı genel yöntemler (indirme veya kaydetme, giriş gömme boyutlarını yeniden boyutlandırma, başları budama vb.) için üst sınıf belgelendirmesine bakın.
Bu model aynı zamanda bir PyTorch torch.nn.Module alt sınıfıdır. Bunu standart bir PyTorch Module olarak kullanın ve genel kullanım ve davranışla ilgili tüm konular için PyTorch dokümantasyonuna başvurun.
forward
< source >( input_values: typing.Optional[torch.Tensor] = Nonelabels: typing.Optional[torch.Tensor] = Noneattention_mask: typing.Optional[torch.Tensor] = None**kwargs: *<class 'transformers.utils.generic.TransformersKwargs'> ) → SequenceClassifierOutput or tuple(torch.Tensor)
Parametreler
- input_values (
torch.Tensor, şekli(batch_size, max_length, num_mel_bins)) — Ham ses dalgacığından çıkarılan mel özelliklerinin kayan nokta değerleri. Ham ses dalgacığı, bir.flacveya.wavses dosyasınılist[float]tipinde bir diziye,numpy.ndarrayveyatorch.Tensoriçine yükleyerek elde edilebilir; örneğin torchcodec kütüphanesi (pip install torchcodec) veya soundfile kütüphanesi (pip install soundfile) aracılığıyla. Diziyiinput_featuresiçin hazırlamak için, mel özelliklerini çıkarmak, dolgu yapmak vetorch.Tensortipinde bir tensöre dönüştürmek üzere AutoFeatureExtractor kullanılmalıdır. Bkz. call() - labels (
torch.LongTensor, şekli(batch_size,), isteğe bağlı) — Ses sınıflandırma/geri dönüşüm kaybını hesaplamak için etiketler. Endeksler[0, ..., config.num_labels - 1]aralığında olmalıdır.config.num_labels == 1ise bir geri dönüşüm kaybı (Ortalama Kare kaybı) hesaplanır,config.num_labels > 1ise bir sınıflandırma kaybı (Çapraz Entropi) hesaplanır. - attention_mask (
torch.Tensorşeklinde(batch_size, sequence_length), isteğe bağlı) — Doldurma (padding) token indekslerinde dikkat (attention) işlemi yapmaktan kaçınmak için kullanılan maske. Seçilen maske değerleri[0, 1]:- 1, maskelenmemiş jetonlar için,
- maskelenmiş jetonlar için 0.
Dönüş değeri
SequenceClassifierOutput veya tuple(torch.Tensor)
Bir SequenceClassifierOutput veya
torch.Tensor demeti (return_dict=False geçirildiğinde veya config.return_dict=False olduğunda), yapılandırmaya (ASTConfig) ve girdilere bağlı olarak çeşitli öğelerden oluşur.
ASTForAudioClassification forward metodu, __call__ özel metodunu geçersiz kılar.
İleri geçiş tarifi bu fonksiyon içinde tanımlanmalı olsa da, sonrasında bunun yerine
Moduleörneğini çağırmak gerekir; çünkü önceki, ön ve son işleme adımlarını çalıştırmaktan sorumluyken ikincisi bunları sessizce yok sayar.
loss (
torch.Tensor, şekli(1,), isteğe bağlı,labelssağlandığında döndürülür) — Sınıflandırma (config.num_labels==1 ise regresyon) kaybı.logits (
torch.Tensor, şekli(batch_size, config.num_labels)) — Sınıflandırma (veya config.num_labels==1 ise regresyon) puanları (SoftMax öncesi).hidden_states (
tuple(torch.Tensor), isteğe bağlı,output_hidden_states=Truegeçirildiğinde veyaconfig.output_hidden_states=Trueolduğunda döndürülür) —torch.Tensor(modelin bir gömme katmanı varsa gömme katmanının çıktısı için bir tane + her katmanın çıktısı için birer tane) içeren,(batch_size, sequence_length, hidden_size)biçiminde bir demet.Her katmanın çıktısında modelin gizli durumları ve isteğe bağlı başlangıç gömme çıktıları.
attentions (
tuple(torch.Tensor), isteğe bağlı,output_attentions=Truegeçirildiğinde veyaconfig.output_attentions=Trueolduğunda döndürülür) —torch.Tensor(katman başına bir tane) içeren bir tuple, şekli(batch_size, num_heads, sequence_length, sequence_length).Dikkat softmax'ı sonrası dikkat ağırlıkları, öz-dikkat başlıklarında ağırlıklı ortalamanın hesaplanmasında kullanılır.
Örnek:
>>> from transformers import AutoFeatureExtractor, ASTForAudioClassification
>>> from datasets import load_dataset
>>> import torch
>>> dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation")
>>> dataset = dataset.sort("id")
>>> sampling_rate = dataset.features["audio"].sampling_rate
>>> feature_extractor = AutoFeatureExtractor.from_pretrained("MIT/ast-finetuned-audioset-10-10-0.4593")
>>> model = ASTForAudioClassification.from_pretrained("MIT/ast-finetuned-audioset-10-10-0.4593")
>>> # audio file is decoded on the fly
>>> inputs = feature_extractor(dataset[0]["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")
>>> with torch.no_grad():
... logits = model(**inputs).logits
>>> predicted_class_ids = torch.argmax(logits, dim=-1).item()
>>> predicted_label = model.config.id2label[predicted_class_ids]
>>> predicted_label
...
>>> # compute loss - target_label is e.g. "down"
>>> target_label = model.config.id2label[0]
>>> inputs["labels"] = torch.tensor([model.config.label2id[target_label]])
>>> loss = model(**inputs).loss
>>> round(loss.item(), 2)
...