How to use d_h1 method in fMBT

Best Python code snippet using fMBT_python

higru_model.py

Source:higru_model.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2'''3Created on : Friday 19 Jun, 2020 : 18:47:024Last Modified : Friday 19 Jun, 2020 : 23:34:005@author : Rishabh Joshi6Institute : Carnegie Mellon University7'''8import sys9sys.path.append('../')10from helper import *11PAD_IDX = 012# Dot-product attention13def get_attention(q, k, v, attn_mask=None):14 """15 :param : (batch, seq_len, seq_len) attn_mask : num_conv x max_seq_len 16 :return: (batch, seq_len, seq_len)17 """18 attn = torch.matmul(q, k.transpose(1, 2)) # num_conv x max_seq_len x max_seq_len19 if attn_mask is not None:20 attn.data.masked_fill_(attn_mask, -1e10)21 #attn.data.masked_fill_(attn_mask.unsqueeze(1) == 1, -1e10) # had to unsqueeze and make boolean22 attn = F.softmax(attn, dim=-1) # num_conv x seq_len x seq_len23 output = torch.matmul(attn, v) # num_conv x seq_len x 30024 return output, attn25# Get mask for attention26def get_attn_pad_mask(seq_q, seq_k):27 assert seq_q.dim() == 2 and seq_k.dim() == 228 pad_attn_mask = torch.matmul(seq_q.unsqueeze(2).float(), seq_k.unsqueeze(1).float())29 pad_attn_mask = pad_attn_mask.eq(PAD_IDX) # b_size x num_utt x 1 x len_k # that 1 is len_k30 #print(pad_attn_mask)31 return pad_attn_mask.to(seq_k.device)32# Pad for utterances with variable lengths and maintain the order of them after GRU33class GRUencoder(nn.Module):34 def __init__(self, d_emb, d_out, num_layers):35 super(GRUencoder, self).__init__()36 # default encoder 2 layers37 self.gru = nn.GRU(input_size=d_emb, hidden_size=d_out,38 bidirectional=True, num_layers=num_layers, dropout=0.3)39 def forward(self, sent, sent_lens):40 """41 :param sent: torch tensor, batch_size x seq_len x d_rnn_in # num_conv x max_utt_len x 76842 :param sent_lens: numpy tensor, batch_size x 1 # arr43 :return:44 """45 device = sent.device46 # seq_len x batch_size x d_rnn_in47 sent_old = sent.clone()48 sent_lens_old = sent_lens.clone()49 sent = sent[sent_lens != 0]50 sent_lens = sent_lens[sent_lens != 0]51 sent_embs = sent.transpose(0,1)52 # sort by length53 #s_lens, idx_sort = np.sort(sent_lens)[::-1], np.argsort(-sent_lens)54 s_lens, idx_sort = torch.sort(sent_lens, descending=True)55 #idx_unsort = np.argsort(idx_sort)56 idx_unsort = torch.argsort(idx_sort)57 #idx_sort = torch.from_numpy(idx_sort).cuda(device)58 s_embs = sent_embs.index_select(1, Variable(idx_sort)) # seq_len x num_conv x 76859 # padding60 sent_packed = pack_padded_sequence(s_embs, s_lens)61 sent_output = self.gru(sent_packed)[0]62 sent_output = pad_packed_sequence(sent_output, total_length=sent.size(1))[0] # seq_len x num_conv x 60063 # unsort by length64 #idx_unsort = torch.from_numpy(idx_unsort).cuda(device)65 sent_output = sent_output.index_select(1, Variable(idx_unsort))66 # batch x seq_len x 2*d_out67 output = sent_output.transpose(0,1)68 final_output = torch.zeros((sent_old.shape[0], sent_old.shape[1], output.shape[-1])).to(sent.device)69 try:70 final_output[torch.where(sent_lens_old != 0)] = output71 except:72 final_output[torch.nonzero(sent_lens_old != 0).view(-1)] = output73 return final_output74# Utterance encoder with three types: higru, higru-f, and higru-sf75class UttEncoder(nn.Module):76 def __init__(self, d_word_vec, d_h1, type):77 super(UttEncoder, self).__init__()78 self.encoder = GRUencoder(d_word_vec, d_h1, num_layers=2)79 self.d_input = 2 * d_h180 self.model = type81 if self.model == 'higru-f':82 self.d_input = 2 * d_h1 + d_word_vec83 if self.model == 'higru-sf':84 self.d_input = 4 * d_h1 + d_word_vec85 self.output1 = nn.Sequential(86 nn.Linear(self.d_input, d_h1),87 nn.Tanh()88 )89 def forward(self, sents, lengths, sa_mask=None):90 """91 :param sents: batch x seq_len x 2*d_h1 # num_conv x max_seq_len x 76892 :param lengths: numpy array 1 x batch # num_conv93 :param sa_mask # num_conv x max_seq_len94 :return: batch x d_h195 """96 w_context = self.encoder(sents, lengths) # num_conv x max_seq_len x 60097 combined = w_context98 if self.model == 'higru-f':99 w_lcont, w_rcont = w_context.chunk(2, -1)100 combined = [w_lcont, sents, w_rcont]101 combined = torch.cat(combined, dim=-1)102 if self.model == 'higru-sf':103 w_lcont, w_rcont = w_context.chunk(2, -1)104 sa_lcont, _ = get_attention(w_lcont, w_lcont, w_lcont, attn_mask=sa_mask)105 sa_rcont, _ = get_attention(w_rcont, w_rcont, w_rcont, attn_mask=sa_mask)106 combined = [sa_lcont, w_lcont, sents, w_rcont, sa_rcont]107 combined = torch.cat(combined, dim=-1)108 output1 = self.output1(combined)109 output = torch.max(output1, dim=1)[0]110 return output111# The overal HiGRU model with three types: HiGRU, HiGRU-f, HiGRU-sf112class HiGRUold(nn.Module):113 def __init__(self, d_word_vec, d_h1, d_h2, d_fc, emodict, worddict, embedding, type='higru'):114 super(HiGRU, self).__init__()115 self.model = type116 self.max_length = worddict.max_length117 #self.max_dialog = worddict.max_dialog118 self.d_h2 = d_h2119 # load word2vec120 self.embeddings = embedding121 self.uttenc = UttEncoder(d_word_vec, d_h1, self.model)122 self.dropout_in = nn.Dropout(0.5)123 self.contenc = nn.GRU(d_h1, d_h2, num_layers=1, bidirectional=True)124 self.d_input = 2 * d_h2125 if self.model == 'higru-f':126 self.d_input = 2 * d_h2 + d_h1127 if self.model == 'higru-sf':128 self.d_input = 4 * d_h2 + d_h1129 self.output1 = nn.Sequential(130 nn.Linear(self.d_input, d_h2),131 nn.Tanh()132 )133 self.dropout_mid = nn.Dropout(0.5)134 self.num_classes = emodict.n_words135 self.classifier = nn.Sequential(136 nn.Linear(d_h2, d_fc),137 nn.Dropout(0.5),138 nn.Linear(d_fc, self.num_classes)139 )140 def forward(self, sents, lens):141 """142 :param sents: batch x seq_len143 :param lens: 1 x batch144 :return:145 """146 if len(sents.size()) < 2:147 sents = sents.unsqueeze(0)148 w_embed = self.embeddings(sents)149 sa_mask = get_attn_pad_mask(sents, sents)150 s_embed = self.uttenc(w_embed, lens, sa_mask)151 s_embed = self.dropout_in(s_embed) # batch x d_h1152 s_context = self.contenc(s_embed.unsqueeze(1))[0]153 s_context = s_context.transpose(0,1).contiguous()154 Combined = s_context155 if self.model == 'higru-f':156 s_lcont, s_rcont = s_context.chunk(2,-1)157 Combined = [s_lcont, s_embed.unsqueeze(0), s_rcont]158 Combined = torch.cat(Combined, dim=-1)159 if self.model == 'higru-sf':160 s_lcont, s_rcont = s_context.chunk(2, -1)161 SA_lcont, _ = get_attention(s_lcont, s_lcont, s_lcont)162 SA_rcont, _ = get_attention(s_rcont, s_rcont, s_rcont)163 Combined = [SA_lcont, s_lcont, s_embed.unsqueeze(0), s_rcont, SA_rcont]164 Combined = torch.cat(Combined, dim=-1)165 output1 = self.output1(Combined.squeeze(0))166 output1 = self.dropout_mid(output1)167 output = self.classifier(output1)168 pred_scores = F.log_softmax(output, dim=1)...

Full Screen

Full Screen

model.py

Source:model.py Github

copy

Full Screen

1__author__ = "Nikhil Mehta"2__copyright__ = "--"3#---------------------------4import tensorflow as tf5import numpy as np6import sys7from util import xavier_init, initialize_weights8class Adversarial_Generator:9 def __init__(self, config):10 self.trainable = True11 self.config = config12 def G (self, z, c, reuse=None, is_training=True):13 with tf.variable_scope('generator', reuse=reuse):14 inputs = tf.concat(axis=1, values=[z, c])15 G_h1 = self.fc_layer(inputs, self.config.z_dim+self.config.attr_dim, self.config.gh1_dim, 'h1')16 G_h1 = tf.nn.relu(G_h1)17 #G_h1 = batch_norm(name='bn_h1')(G_h1, phase=is_training)18 G_h2 = self.fc_layer(G_h1, self.config.gh1_dim, self.config.gh2_dim, 'h2')19 G_h2 = tf.nn.relu(G_h2)20 #G_h2 = batch_norm(name='bn_h2')(G_h2, phase=is_training)21 22 G_out = self.fc_layer(G_h2, self.config.gh2_dim, self.config.x_dim, 'out')23 G_out = tf.tanh(G_out)24 25 return G_out26 def D (self, x, c, reuse=None, bn_name='same'):27 """ bn_name useful for batch_norm. Separate batch for real/fake"""28 with tf.variable_scope('discriminator', reuse=reuse) as d_scope:29 #x = self.dropout(x, 0.5, name="x_dropout")30 inputs = tf.concat(axis=1, values=[x, c])31 32 D_h1 = self.fc_layer(inputs, self.config.x_dim+self.config.attr_dim, self.config.dh1_dim, 'h1')33 D_h1 = tf.nn.leaky_relu(D_h1)34 #D_h1 = batch_norm(name='bn_h1')(D_h1)35 #D_h2 = self.fc_layer(D_h1, self.config.dh1_dim, self.config.dh2_dim, 'h2')36 #D_h2 = tf.nn.leaky_relu(D_h2)37 #D_h2 = batch_norm(name='bn_h2')(D_h2)38 39 D_logit = self.fc_layer(D_h1, self.config.dh1_dim, 1, 'out')40 D_prob = tf.nn.sigmoid(D_logit)41 42 return D_prob, D_logit43 def loss (self, x, z, c):44 x_gen = self.G(z, c)45 D_real, D_logit_real = self.D(x, c, bn_name='real')46 # reuse47 D_fake, D_logit_fake = self.D(x_gen, c, reuse=True, bn_name='fake')48 reverse_D_real, reverse_D_logit_real = self.D(x_gen, c, reuse=True, bn_name='fake')49 reverse_D_fake, reverse_D_logit_fake = self.D(x, c, reuse=True, bn_name='real')50 51 D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_real, labels=tf.ones_like(D_logit_real)))52 D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake, labels=tf.zeros_like(D_logit_fake)))53 D_loss = D_loss_real + D_loss_fake54 reverse_D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=reverse_D_logit_real, labels=tf.ones_like(reverse_D_logit_real)))55 reverse_D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=reverse_D_logit_fake, labels=tf.zeros_like(reverse_D_logit_fake)))56 reverse_D_loss = reverse_D_loss_real + reverse_D_loss_fake57 58 G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake, labels=tf.ones_like(D_logit_fake)))59 with tf.variable_scope('discriminator'):60 tf.summary.scalar("discriminator_loss", D_loss)61 62 with tf.variable_scope('generator'):63 tf.summary.scalar("generator_loss", G_loss)64 65 return G_loss, D_loss, reverse_D_loss66 # ------------------WGAN------------------------------67 def D_WGAN (self, x, c, reuse=None, bn_name='same'):68 """ bn_name useful for batch_norm. Separate batch for real/fake"""69 with tf.variable_scope('discriminator', reuse=reuse) as d_scope:70 inputs = tf.concat(axis=1, values=[x, c])71 72 D_h1 = self.fc_layer(inputs, self.config.x_dim+self.config.attr_dim, self.config.dh1_dim, 'h1')73 D_h1 = tf.nn.leaky_relu(D_h1)74 75 D_logit = self.fc_layer(D_h1, self.config.dh1_dim, 1, 'out')76 return D_logit77 def loss_WGAN (self, x, z, c):78 x_gen = self.G(z, c)79 D_logit_real = self.D_WGAN(x, c, bn_name='real')80 # reuse81 D_logit_fake = self.D_WGAN(x_gen, c, reuse=True, bn_name='fake')82 D_loss = tf.reduce_mean(D_logit_fake) - tf.reduce_mean(D_logit_real) 83 G_loss = - tf.reduce_mean(D_logit_fake)84 with tf.variable_scope('discriminator'):85 tf.summary.scalar("discriminator_loss", D_loss)86 87 with tf.variable_scope('generator'):88 tf.summary.scalar("generator_loss", G_loss)89 90 return G_loss, D_loss91 def fc_layer(self, input_data, in_size, out_size, name):92 with tf.variable_scope(name):93 W, b = self.get_fc_var(in_size, out_size, name)94 out = tf.matmul(input_data, W) + b95 96 return out97 def get_fc_var(self, in_size, out_size, name):98 initial_value = initialize_weights([in_size, out_size])99 #initial_value = xavier_init([in_size, out_size])100 W = tf.get_variable(name='weight', initializer=initial_value)101 initial_value = tf.zeros(shape=[out_size])102 b = tf.get_variable(name='bias', initializer=initial_value)103 return W, b104 def dropout(self, bottom, keep_prob, name):105 return tf.nn.dropout(bottom, keep_prob, name=name)106class batch_norm(object):107 108 #def __init__(self, epsilon=1e-5, momentum = 0.99, name="batch_norm"):109 def __init__(self, name="batch_norm"):110 with tf.variable_scope(name):111 #self.epsilon = epsilon112 #self.momentum = momentum113 self.name = name114 # Keep phase True for both train and test case for GANs115 def __call__(self, x, phase=True):116 return tf.contrib.layers.batch_norm(x,117 #decay=self.momentum, 118 #epsilon=self.epsilon,119 scale=True,120 center=True, 121 is_training=phase,...

Full Screen

Full Screen

match_5_split.py

Source:match_5_split.py Github

copy

Full Screen

1import numpy as np2import os, sys3import json4import random5import hungarian6import os7os.system('cat ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt ../WEB_3D3_2.txt > WEB_3D3_.txt')8print('Loading S')9imgs = np.loadtxt(open('S_features.csv','rb'),delimiter=',',skiprows=0)10imgs = np.concatenate((imgs, imgs), axis=0)11imgs = np.concatenate((imgs, imgs), axis=0)12imgs = np.concatenate((imgs, imgs), axis=0)13paths = open('./WEB_3D3_.txt','r').readlines()14print('Loading T')15imgs_web = np.loadtxt(open('T_features.csv','rb'),delimiter=',',skiprows=0)16paths_web = open('./new_AwA2.txt','r').readlines()17print('Loaded !')18L = imgs.shape[0]19print(L)20print(imgs.shape[0])21print(imgs.shape[1])22shuffle = [i for i in range(L)]23random.shuffle(shuffle)24Tail = imgs_web.shape[0] - imgs.shape[0]25imgs = np.concatenate((imgs, imgs[shuffle[:Tail]]), axis=0)26print(len(paths))27paths_tail = [paths[i] for i in shuffle[:Tail]]28paths = paths + paths_tail29L = imgs_web.shape[0]30shuffle = [i for i in range(L)]31random.shuffle(shuffle)32imgs_web = imgs_web[shuffle]33paths_web = [paths_web[i] for i in shuffle]34random.shuffle(shuffle)35imgs = imgs[shuffle]36paths = [paths[i] for i in shuffle]37d_h1 = imgs[:8500].astype(np.float32)38d_h2 = imgs_web[:8500].astype(np.float32)39L1_ = np.zeros((d_h1.shape[0], d_h2.shape[0]))40ws = []41BSZ = 5042for i in range(int(d_h1.shape[0]/BSZ)+1):43 print(i)44 if i!=int(d_h1.shape[0]/BSZ):45 d_h1_ = np.repeat(d_h1[int(i*BSZ):int((i+1)*BSZ)], d_h2.shape[0], axis=0)46 d_h2_ = np.tile(d_h2, [BSZ,1])47 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)48 L1_[int(i*BSZ):int((i+1)*BSZ),:] = np.reshape(L1, (BSZ, d_h2.shape[0]))49 else:50 d_h1_ = np.repeat(d_h1[int(i*BSZ):], d_h2.shape[0], axis=0)51 d_h2_ = np.tile(d_h2, [int(d_h1.shape[0]%BSZ),1])52 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)53 L1_[int(i*BSZ):,:] = np.reshape(L1, (int(d_h1.shape[0]%BSZ), d_h2.shape[0]))54obj_matrix = L1_55f=open('COR1.txt','w')56print('Begin')57rs, cs = hungarian.lap(obj_matrix)58print('Write result')59for i in range(8500):60 f.write(paths[i][:-1]+' '+ paths_web[rs[i]])61f.close()62f=open('COR2.txt','w')63d_h1 = imgs[8500:17000].astype(np.float32)64d_h2 = imgs_web[8500:17000].astype(np.float32)65L1_ = np.zeros((d_h1.shape[0], d_h2.shape[0]))66ws = []67BSZ = 5068for i in range(int(d_h1.shape[0]/BSZ)+1):69 print(i)70 if i!=int(d_h1.shape[0]/BSZ):71 d_h1_ = np.repeat(d_h1[int(i*BSZ):int((i+1)*BSZ)], d_h2.shape[0], axis=0)72 d_h2_ = np.tile(d_h2, [BSZ,1])73 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)74 L1_[int(i*BSZ):int((i+1)*BSZ),:] = np.reshape(L1, (BSZ, d_h2.shape[0]))75 else:76 d_h1_ = np.repeat(d_h1[int(i*BSZ):], d_h2.shape[0], axis=0)77 d_h2_ = np.tile(d_h2, [int(d_h1.shape[0]%BSZ),1])78 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)79 L1_[int(i*BSZ):,:] = np.reshape(L1, (int(d_h1.shape[0]%BSZ), d_h2.shape[0]))80obj_matrix = L1_81print('Begin')82rs, cs = hungarian.lap(obj_matrix)83print('Write result')84for i in range(8500):85 f.write(paths[i+8500][:-1]+' '+ paths_web[rs[i]+8500])86f.close()87f=open('COR3.txt','w')88d_h1 = imgs[17000:25500].astype(np.float32)89d_h2 = imgs_web[17000:25500].astype(np.float32)90L1_ = np.zeros((d_h1.shape[0], d_h2.shape[0]))91ws = []92BSZ = 5093for i in range(int(d_h1.shape[0]/BSZ)+1):94 print(i)95 if i!=int(d_h1.shape[0]/BSZ):96 d_h1_ = np.repeat(d_h1[int(i*BSZ):int((i+1)*BSZ)], d_h2.shape[0], axis=0)97 d_h2_ = np.tile(d_h2, [BSZ,1])98 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)99 L1_[int(i*BSZ):int((i+1)*BSZ),:] = np.reshape(L1, (BSZ, d_h2.shape[0]))100 else:101 d_h1_ = np.repeat(d_h1[int(i*BSZ):], d_h2.shape[0], axis=0)102 d_h2_ = np.tile(d_h2, [int(d_h1.shape[0]%BSZ),1])103 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)104 L1_[int(i*BSZ):,:] = np.reshape(L1, (int(d_h1.shape[0]%BSZ), d_h2.shape[0]))105obj_matrix = L1_106print('Begin')107rs, cs = hungarian.lap(obj_matrix)108print('Write result')109for i in range(8500):110 f.write(paths[i+17000][:-1]+' '+ paths_web[rs[i]+17000])111f.close()112f=open('COR4.txt','w')113d_h1 = imgs[25500:34000].astype(np.float32)114d_h2 = imgs_web[25500:34000].astype(np.float32)115L1_ = np.zeros((d_h1.shape[0], d_h2.shape[0]))116ws = []117BSZ = 50118for i in range(int(d_h1.shape[0]/BSZ)+1):119 print(i)120 if i!=int(d_h1.shape[0]/BSZ):121 d_h1_ = np.repeat(d_h1[int(i*BSZ):int((i+1)*BSZ)], d_h2.shape[0], axis=0)122 d_h2_ = np.tile(d_h2, [BSZ,1])123 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)124 L1_[int(i*BSZ):int((i+1)*BSZ),:] = np.reshape(L1, (BSZ, d_h2.shape[0]))125 else:126 d_h1_ = np.repeat(d_h1[int(i*BSZ):], d_h2.shape[0], axis=0)127 d_h2_ = np.tile(d_h2, [int(d_h1.shape[0]%BSZ),1])128 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)129 L1_[int(i*BSZ):,:] = np.reshape(L1, (int(d_h1.shape[0]%BSZ), d_h2.shape[0]))130obj_matrix = L1_131print('Begin')132rs, cs = hungarian.lap(obj_matrix)133print('Write result')134for i in range(min(8500,8268)):135 f.write(paths[i+25500][:-1]+' '+ paths_web[rs[i]+25500])136f.close()137f=open('COR5.txt','w')138d_h1 = imgs[34000:].astype(np.float32)139d_h2 = imgs_web[34000:].astype(np.float32)140L1_ = np.zeros((d_h1.shape[0], d_h2.shape[0]))141ws = []142BSZ = 50143for i in range(int(d_h1.shape[0]/BSZ)+1):144 print(i)145 if i!=int(d_h1.shape[0]/BSZ):146 d_h1_ = np.repeat(d_h1[int(i*BSZ):int((i+1)*BSZ)], d_h2.shape[0], axis=0)147 d_h2_ = np.tile(d_h2, [BSZ,1])148 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)149 L1_[int(i*BSZ):int((i+1)*BSZ),:] = np.reshape(L1, (BSZ, d_h2.shape[0]))150 else:151 d_h1_ = np.repeat(d_h1[int(i*BSZ):], d_h2.shape[0], axis=0)152 d_h2_ = np.tile(d_h2, [int(d_h1.shape[0]%BSZ),1])153 L1 = np.sum(np.abs(d_h1_ - d_h2_), 1)154 L1_[int(i*BSZ):,:] = np.reshape(L1, (int(d_h1.shape[0]%BSZ), d_h2.shape[0]))155obj_matrix = L1_156print('Begin')157rs, cs = hungarian.lap(obj_matrix)158print('Write result')159for i in range(len(imgs)-34000):160 f.write(paths[i+34000][:-1]+' '+ paths_web[rs[i]+34000])161f.close()...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fMBT automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful