cari
RumahPeranti teknologiAIRingkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama

Pembelajaran berterusan merujuk kepada model yang mempelajari sejumlah besar tugasan secara berurutan tanpa melupakan pengetahuan yang diperoleh daripada tugasan sebelumnya. Ini merupakan konsep penting kerana, di bawah pembelajaran diselia, model pembelajaran mesin dilatih untuk menjadi fungsi terbaik untuk set data atau pengedaran data tertentu. Dalam persekitaran kehidupan sebenar, data jarang statik dan mungkin berubah. Model ML biasa boleh mengalami kemerosotan prestasi apabila berhadapan dengan data yang tidak kelihatan. Fenomena ini dipanggil pelupaan bencana.

Ringkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama

Cara biasa untuk menyelesaikan jenis masalah ini ialah melatih semula keseluruhan model pada set data baharu yang lebih besar yang mengandungi data lama dan baharu. Tetapi pendekatan ini selalunya mahal. Oleh itu, terdapat bidang penyelidikan ML yang mengkaji masalah ini Berdasarkan penyelidikan dalam bidang ini, artikel ini akan membincangkan 6 kaedah supaya model dapat menyesuaikan diri dengan data baru sambil mengekalkan prestasi lama dan mengelakkan keperluan untuk melaksanakan. keseluruhan set data (lama + baharu) untuk dilatih semula.

Prompt

Prompt Idea berpunca daripada idea bahawa pembayang (urutan perkataan pendek) untuk GPT 3 boleh membantu mendorong model untuk menaakul dan menjawab dengan lebih baik. Jadi Prompt diterjemahkan sebagai prompt dalam artikel ini. Penalaan petunjuk merujuk kepada menggunakan pembayang kecil yang boleh dipelajari dan memberinya sebagai input kepada model bersama dengan input sebenar. Ini membolehkan kami hanya melatih model kecil yang memberikan petunjuk tentang data baharu tanpa perlu melatih semula berat model.

Secara khusus, saya memilih contoh penggunaan gesaan untuk mendapatkan semula intensif berasaskan teks, yang diadaptasi daripada artikel Wang "Belajar untuk Mendorong Pembelajaran berterusan".

Pengarang makalah menerangkan idea mereka menggunakan rajah berikut:

Ringkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama

Input teks yang dikodkan sebenar digunakan untuk mengenal pasti pasangan padanan minimum daripada gesaan kunci kolam. Isyarat yang dikenal pasti ini terlebih dahulu ditambahkan pada benam teks yang tidak dikodkan sebelum ia dimasukkan ke dalam model. Tujuannya adalah untuk melatih gesaan ini untuk mewakili tugasan baharu sambil mengekalkan model lama tidak berubah Gesaan di sini adalah sangat kecil, mungkin hanya 20 token setiap gesaan.

class PromptPool(nn.Module):
def __init__(self, M = 100, hidden_size = 768, length = 20, N=5):
super().__init__()
self.pool = nn.Parameter(torch.rand(M, length, hidden_size), requires_grad=True).float()
self.keys = nn.Parameter(torch.rand(M, hidden_size), requires_grad=True).float()
 
self.length = length
self.hidden = hidden_size
self.n = N
 
nn.init.xavier_normal_(self.pool)
nn.init.xavier_normal_(self.keys)
 
def init_weights(self, embedding):
pass
 
# function to select from pool based on index
def concat(self, indices, input_embeds):
subset = self.pool[indices, :] # 2, 2, 20, 768
 
subset = subset.to("cuda:0").reshape(indices.size(0),
self.n*self.length,
self.hidden) # 2, 40, 768
 
return torch.cat((subset, input_embeds), 1)
 
# x is cls output
def query_fn(self, x):
 
# encode input x to same dim as key using cosine
x = x / x.norm(dim=1)[:, None]
k = self.keys / self.keys.norm(dim=1)[:, None]
 
scores = torch.mm(x, k.transpose(0,1).to("cuda:0"))
 
# get argmin
subsets = torch.topk(scores, self.n, 1, False).indices # k smallest
 
return subsets
 
 pool = PromptPool()

Kemudian kami menggunakan model data lama yang terlatih untuk melatih data baharu Di sini kami hanya melatih berat bahagian gesaan.

def train():
count = 0
print("*********** Started Training *************")
 
start = time.time()
for epoch in range(40):
model.eval()
pool.train()
 
optimizer.zero_grad(set_to_none=True)
lap = time.time()
 
for batch in iter(train_dataloader):
count += 1
q, p, train_labels = batch
 
queries_emb = model(input_ids=q['input_ids'].to("cuda:0"),
attention_mask=q['attention_mask'].to("cuda:0"))
passage_emb = model(input_ids=p['input_ids'].to("cuda:0"),
attention_mask=p['attention_mask'].to("cuda:0"))
 
# pool
q_idx = pool.query_fn(queries_emb)
raw_qembedding = model.model.embeddings(input_ids=q['input_ids'].to("cuda:0"))
q = pool.concat(indices=q_idx, input_embeds=raw_qembedding)
 
p_idx = pool.query_fn(passage_emb)
raw_pembedding = model.model.embeddings(input_ids=p['input_ids'].to("cuda:0"))
p = pool.concat(indices=p_idx, input_embeds=raw_pembedding)
 
qattention_mask = torch.ones(batch_size, q.size(1))
pattention_mask = torch.ones(batch_size, p.size(1))
 
queries_emb = model.model(inputs_embeds=q,
attention_mask=qattention_mask.to("cuda:0")).last_hidden_state
passage_emb = model.model(inputs_embeds=p,
attention_mask=pattention_mask.to("cuda:0")).last_hidden_state
 
q_cls = queries_emb[:, pool.n*pool.length+1, :]
p_cls = passage_emb[:, pool.n*pool.length+1, :]
 
loss, ql, pl = calc_loss(q_cls, p_cls)
loss.backward()
 
optimizer.step()
optimizer.zero_grad(set_to_none=True)
 
if count % 10 == 0:
print("Model Loss:", round(loss.item(),4), 
"| QL:", round(ql.item(),4), "| PL:", round(pl.item(),4), 
"| Took:", round(time.time() - lap), "secondsn")
 
lap = time.time()
 
if count % 40 == 0 and count > 0:
print("model saved")
torch.save(model.state_dict(), model_PATH)
torch.save(pool.state_dict(), pool_PATH)
 
if count == 4600: return
 
print("Training Took:", round(time.time() - start), "seconds")
print("n*********** Training Complete *************")

Selepas latihan selesai, proses inferens seterusnya perlu menggabungkan input dengan pembayang yang diambil. Contohnya, contoh ini mendapat prestasi -93% untuk kumpulan petunjuk data baharu dan -94% untuk latihan penuh (lama + baharu). Ini serupa dengan prestasi yang dinyatakan dalam kertas asal. Tetapi kaveatnya ialah keputusan mungkin berbeza-beza bergantung pada tugasan, dan anda harus mencuba eksperimen untuk mengetahui perkara yang paling berkesan.

Untuk kaedah ini berbaloi untuk dipertimbangkan, ia mesti dapat mengekalkan >80% prestasi model lama pada data lama, manakala pembayang juga harus membantu model mencapai prestasi yang baik pada data baharu.

Kelemahan kaedah ini ialah ia memerlukan penggunaan kolam pembayang, yang menambah masa tambahan. Ini bukan penyelesaian kekal, tetapi ia boleh dilaksanakan buat masa ini, dan mungkin kaedah baharu akan muncul pada masa hadapan.

Penyulingan Data

Anda mungkin pernah mendengar istilah penyulingan pengetahuan, iaitu teknik yang menggunakan pemberat daripada model guru untuk membimbing dan melatih model berskala lebih kecil. Penyulingan Data berfungsi sama, menggunakan pemberat daripada data sebenar untuk melatih subset data yang lebih kecil. Oleh kerana isyarat utama set data diperhalusi dan dipadatkan kepada set data yang lebih kecil, latihan kami tentang data baharu hanya perlu disediakan dengan beberapa data yang diperhalusi untuk mengekalkan prestasi lama.

Dalam contoh ini, saya menggunakan penyulingan data pada tugas mendapatkan semula (teks) padat. Tiada orang lain yang menggunakan kaedah ini dalam bidang ini pada masa ini, jadi hasilnya mungkin bukan yang terbaik, tetapi jika anda menggunakan kaedah ini pada pengelasan teks, anda sepatutnya mendapat hasil yang baik.

Pada asasnya, idea penyulingan data teks berasal daripada kertas oleh Li bertajuk Penyulingan Data untuk Pengelasan Teks, yang diilhamkan oleh Penyulingan Set Data Wang, di mana beliau menyuling data imej. Li menerangkan tugas penyulingan data teks dengan gambar rajah berikut:

Ringkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama

Menurut kertas kerja, sekumpulan data suling dimasukkan dahulu ke dalam model untuk mengemas kini beratnya. Model yang dikemas kini kemudian dinilai menggunakan data sebenar dan isyarat disebarkan semula ke set data suling. Makalah ini melaporkan hasil pengelasan yang baik (>80% ketepatan) pada 8 set data penanda aras awam.

Berikutan idea yang dicadangkan, saya membuat beberapa perubahan kecil dan menggunakan sekumpulan data suling dan berbilang data sebenar. Berikut ialah kod untuk mencipta data suling untuk latihan mendapatkan semula intensif:

class DistilledData(nn.Module):
def __init__(self, num_labels, M, q_len=64, hidden_size=768):
super().__init__()
self.num_samples = M
self.q_len = q_len
self.num_labels = num_labels
self.data = nn.Parameter(torch.rand(num_labels, M, q_len, hidden_size), requires_grad=True) # i.e. shape: 1000, 4, 64, 768
 
# init using model embedding, xavier, or load from state dict
def init_weights(self, model, path=None):
if model:
self.data.requires_grad = False
print("Init weights using model embedding")
raw_embedding = model.model.get_input_embeddings()
soft_embeds = raw_embedding.weight[:, :].clone().detach()
nums = soft_embeds.size(0)
for i1 in range(self.num_labels):
for i2 in range(self.num_samples):
for i3 in range(self.q_len):
random_idx = random.randint(0, nums-1)
self.data[i1, i2, i3, :] = soft_embeds[random_idx, :]
print(self.data.shape)
self.data.requires_grad = True
 
if not path:
nn.init.xavier_normal_(self.data)
else:
distilled_data.load_state_dict(torch.load(path), strict=False)
 
# function to sample a passage and positive sample as in the article, i am doing dense retrieval
def get_sample(self, label):
q_idx = random.randint(0, self.num_samples-1)
sampled_dist_q = self.data[label, q_idx, :, :]
 
p_idx = random.randint(0, self.num_samples-1)
while q_idx == p_idx:
p_idx = random.randint(0, self.num_samples-1)
sampled_dist_p = self.data[label, p_idx, :, :]
 
return sampled_dist_q, sampled_dist_p, q_idx, p_idx

Ini ialah kod untuk mengekstrak isyarat ke data suling

def distll_train(chunk_size=32):
count, times = 0, 0
print("*********** Started Training *************")
start = time.time()
lap = time.time()
 
for epoch in range(40):
distilled_data.train()
 
for batch in iter(train_dataloader):
count += 1
# get real query, pos, label, distilled data query, distilled data pos, ... from batch
q, p, train_labels, dq, dp, q_indexes, p_indexes = batch
 
for idx in range(0, dq['input_ids'].size(0), chunk_size):
model.train()
 
with torch.enable_grad():
# train on distiled data first
x1 = dq['input_ids'][idx:idx+chunk_size].clone().detach().requires_grad_(True)
x2 = dp['input_ids'][idx:idx+chunk_size].clone().detach().requires_grad_(True)
q_emb = model(inputs_embeds=x1.to("cuda:0"),
attention_mask=dq['attention_mask'][idx:idx+chunk_size].to("cuda:0")).cpu()
p_emb = model(inputs_embeds=x2.to("cuda:0"),
attention_mask=dp['attention_mask'][idx:idx+chunk_size].to("cuda:0"))
loss = default_loss(q_emb.to("cuda:0"), p_emb)
del q_emb, p_emb
 
loss.backward(retain_graph=True, create_graph=False)
state_dict = model.state_dict()
 
# update model weights
with torch.no_grad():
for idx, param in enumerate(model.parameters()):
if param.requires_grad and not param.grad is None:
param.data -= (param.grad*3e-5)
 
# real data
model.eval()
q_embs = []
p_embs = []
for k in range(0, len(q['input_ids']), chunk_size):
with torch.no_grad():
q_emb = model(input_ids=q['input_ids'][k:k+chunk_size].to("cuda:0"),).cpu()
p_emb = model(input_ids=p['input_ids'][k:k+chunk_size].to("cuda:0"),).cpu()
q_embs.append(q_emb)
p_embs.append(p_emb)
q_embs = torch.cat(q_embs, 0)
p_embs = torch.cat(p_embs, 0)
r_loss = default_loss(q_embs.to("cuda:0"), p_embs.to("cuda:0"))
del q_embs, p_embs
 
# distill backward
if count % 2 == 0:
d_grad = torch.autograd.grad(inputs=[x1.to("cuda:0")],#, x2.to("cuda:0")],
outputs=loss,
grad_outputs=r_loss)
indexes = q_indexes
else:
d_grad = torch.autograd.grad(inputs=[x2.to("cuda:0")],
outputs=loss,
grad_outputs=r_loss)
indexes = p_indexes
loss.detach()
r_loss.detach()
 
grads = torch.zeros(distilled_data.data.shape) # lbl, 10, 100, 768
for i, k in enumerate(indexes):
grads[train_labels[i], k, :, :] = grads[train_labels[i], k, :, :].to("cuda:0") 
+ d_grad[0][i, :, :]
distilled_data.data.grad = grads
data_optimizer.step()
data_optimizer.zero_grad(set_to_none=True)
 
model.load_state_dict(state_dict)
model_optimizer.step()
model_optimizer.zero_grad(set_to_none=True)
 
if count % 10 == 0:
print("Count:", count ,"| Data:", round(loss.item(), 4), "| Model:", 
round(r_loss.item(),4), "| Time:", round(time.time() - lap, 4))
# print()
lap = time.time()
 
if count % 100 == 0:
torch.save(model.state_dict(), model_PATH)
torch.save(distilled_data.state_dict(), distill_PATH)
 
if loss < 0.1 and r_loss < 1:
times += 1
 
if times > 100:
print("Training Took:", round(time.time() - start), "seconds")
print("n*********** Training Complete *************")
return
del loss, r_loss, grads, q, p, train_labels, dq, dp, x1, x2, state_dict
 
print("Training Took:", round(time.time() - start), "seconds")
print("n*********** Training Complete *************")

Kod seperti pemuatan data, latihan dikecualikan di sini Setelah kami menyaring data, kami boleh menggunakannya dengan melatih model baharu padanya, contohnya dengan menggabungkannya dengan data baharu.

Menurut eksperimen saya, model yang dilatih pada data suling (hanya mengandungi 4 sampel setiap label) mencapai prestasi terbaik sebanyak 66%, manakala model yang dilatih sepenuhnya pada data mentah juga mencapai 66% prestasi terbaik. Model biasa yang tidak terlatih mencapai prestasi 45%. Seperti yang dinyatakan di atas nombor ini mungkin tidak baik untuk tugas mendapatkan semula intensif, tetapi akan menjadi lebih baik pada data kategori.

Untuk kaedah ini berguna apabila melaraskan model kepada data baharu, seseorang itu perlu dapat mengekstrak set data yang jauh lebih kecil daripada data asal (iaitu ~1%). Data yang diperhalusi juga boleh memberikan anda prestasi yang lebih rendah sedikit daripada atau sama dengan kaedah pembelajaran aktif.

Kelebihan kaedah ini ialah ia boleh mencipta data suling untuk kegunaan kekal. Kelemahannya ialah data yang diekstrak tidak boleh ditafsir dan memerlukan masa latihan tambahan.

Kurikulum/Latihan aktif

Latihan kurikulum ialah kaedah yang secara beransur-ansur menjadi lebih sukar untuk menyediakan sampel latihan kepada model semasa latihan. Apabila melatih data baharu, kaedah ini memerlukan pelabelan manual tugas, mengklasifikasikan tugas kepada mudah, sederhana atau sukar, dan kemudian mengambil sampel data. Untuk memahami maksud model menjadi mudah, sederhana atau sukar, saya mengambil imej ini sebagai contoh:

Ringkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama

Ini ialah matriks kekeliruan dalam tugas pengelasan, sampel keras adalah palsu Positif (Positif Palsu) merujuk kepada sampel yang model meramalkan kemungkinan besar adalah Benar, tetapi sebenarnya tidak Benar. Sampel sederhana ialah sampel yang mempunyai kebarangkalian sederhana hingga tinggi untuk betul tetapi Negatif Benar di bawah ambang ramalan. Sampel mudah ialah sampel yang mempunyai kemungkinan lebih rendah untuk Benar Positif/Negatif.

Maximally Interfered Retrieval

Ini adalah kaedah yang diperkenalkan oleh Rahaf dalam makalah (1908.04742) bertajuk "Online Continual Learning with Maximally Interfered Retrieval". Idea utama ialah untuk setiap kumpulan data baharu yang dilatih, jika anda mengemas kini berat model untuk data yang lebih baharu, anda perlu mengenal pasti sampel lama yang paling terjejas dari segi nilai kehilangan. Memori saiz terhad yang terdiri daripada data lama dikekalkan dan sampel yang paling mengganggu diambil bersama dengan setiap kumpulan data baharu untuk dilatih bersama.

Kertas ini ialah kertas kerja yang mantap dalam bidang pembelajaran berterusan dan mempunyai banyak petikan, jadi ia boleh digunakan untuk kes anda.

Akmentasi Retrieval

Agmentasi Retrieval merujuk kepada teknik menambah input, sampel, dsb. dengan mendapatkan semula item daripada koleksi. Ini adalah konsep umum dan bukannya teknologi khusus. Kebanyakan kaedah yang telah kami bincangkan setakat ini adalah operasi berkaitan perolehan sedikit sebanyak. Kertas kerja Izacard bertajuk Few-shot Learning with Retrieval Augmented Language Models menggunakan model yang lebih kecil untuk mencapai prestasi cemerlang dalam pembelajaran beberapa pukulan. Peningkatan perolehan juga digunakan dalam banyak situasi lain, seperti penjanaan perkataan atau menjawab soalan fakta.

Melanjutkan model untuk menggunakan lapisan tambahan semasa latihan ialah kaedah yang paling biasa dan paling mudah, tetapi ia tidak semestinya berkesan, jadi ia tidak akan dibincangkan secara terperinci di sini. Contoh di sini ialah Pembelajaran Sedikit Tangkapan Cekap Lewis tanpa Gesaan. Menggunakan lapisan tambahan selalunya merupakan cara yang paling mudah tetapi dicuba dan diuji untuk mendapatkan prestasi yang baik pada data lama dan baharu. Idea utama adalah untuk memastikan berat model tetap dan melatih satu atau beberapa lapisan pada data baharu dengan kehilangan klasifikasi.

Ringkasan Dalam artikel ini, saya memperkenalkan 6 kaedah yang boleh anda gunakan semasa melatih model tentang data baharu. Seperti biasa seseorang itu harus bereksperimen dan memutuskan kaedah mana yang paling berkesan, tetapi penting untuk diperhatikan bahawa terdapat banyak kaedah selain kaedah yang saya ada di atas, contohnya penyulingan data adalah kawasan aktif dalam penglihatan komputer dan anda boleh menemui banyak tentangnya kertas . Nota terakhir: agar kaedah ini bernilai, kaedah ini harus mencapai prestasi yang baik pada kedua-dua data lama dan baharu.

Atas ialah kandungan terperinci Ringkasan enam kaedah biasa pembelajaran berterusan: menyesuaikan model ML kepada data baharu sambil mengekalkan prestasi data lama. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:51CTO.COM. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Cara Membina Pembantu AI Peribadi Anda Dengan Huggingface SmollmCara Membina Pembantu AI Peribadi Anda Dengan Huggingface SmollmApr 18, 2025 am 11:52 AM

Memanfaatkan kuasa AI di peranti: Membina CLI Chatbot Peribadi Pada masa lalu, konsep pembantu AI peribadi kelihatan seperti fiksyen sains. Bayangkan Alex, seorang peminat teknologi, bermimpi seorang sahabat AI yang pintar, yang tidak bergantung

AI untuk Kesihatan Mental dianalisis dengan penuh perhatian melalui inisiatif baru yang menarik di Stanford UniversityAI untuk Kesihatan Mental dianalisis dengan penuh perhatian melalui inisiatif baru yang menarik di Stanford UniversityApr 18, 2025 am 11:49 AM

Pelancaran AI4MH mereka berlaku pada 15 April, 2025, dan Luminary Dr. Tom Insel, M.D., pakar psikiatri yang terkenal dan pakar neurosains, berkhidmat sebagai penceramah kick-off. Dr. Insel terkenal dengan kerja cemerlangnya dalam penyelidikan kesihatan mental dan techno

Kelas Draf WNBA 2025 memasuki liga yang semakin meningkat dan melawan gangguan dalam talianKelas Draf WNBA 2025 memasuki liga yang semakin meningkat dan melawan gangguan dalam talianApr 18, 2025 am 11:44 AM

"Kami mahu memastikan bahawa WNBA kekal sebagai ruang di mana semua orang, pemain, peminat dan rakan kongsi korporat, berasa selamat, dihargai dan diberi kuasa," kata Engelbert, menangani apa yang telah menjadi salah satu cabaran sukan wanita yang paling merosakkan. Anno

Panduan Komprehensif untuk Struktur Data Terbina Python - Analytics VidhyaPanduan Komprehensif untuk Struktur Data Terbina Python - Analytics VidhyaApr 18, 2025 am 11:43 AM

Pengenalan Python cemerlang sebagai bahasa pengaturcaraan, terutamanya dalam sains data dan AI generatif. Manipulasi data yang cekap (penyimpanan, pengurusan, dan akses) adalah penting apabila berurusan dengan dataset yang besar. Kami pernah meliputi nombor dan st

Tayangan pertama dari model baru Openai berbanding dengan alternatifTayangan pertama dari model baru Openai berbanding dengan alternatifApr 18, 2025 am 11:41 AM

Sebelum menyelam, kaveat penting: Prestasi AI adalah spesifik yang tidak ditentukan dan sangat digunakan. Dalam istilah yang lebih mudah, perbatuan anda mungkin berbeza -beza. Jangan ambil artikel ini (atau lain -lain) sebagai perkataan akhir -sebaliknya, uji model ini pada senario anda sendiri

AI Portfolio | Bagaimana untuk membina portfolio untuk kerjaya AI?AI Portfolio | Bagaimana untuk membina portfolio untuk kerjaya AI?Apr 18, 2025 am 11:40 AM

Membina portfolio AI/ML yang menonjol: Panduan untuk Pemula dan Profesional Mewujudkan portfolio yang menarik adalah penting untuk mendapatkan peranan dalam kecerdasan buatan (AI) dan pembelajaran mesin (ML). Panduan ini memberi nasihat untuk membina portfolio

AI AI apa yang boleh dimaksudkan untuk operasi keselamatanAI AI apa yang boleh dimaksudkan untuk operasi keselamatanApr 18, 2025 am 11:36 AM

Hasilnya? Pembakaran, ketidakcekapan, dan jurang yang melebar antara pengesanan dan tindakan. Tak satu pun dari ini harus datang sebagai kejutan kepada sesiapa yang bekerja dalam keselamatan siber. Janji Agentic AI telah muncul sebagai titik perubahan yang berpotensi. Kelas baru ini

Google Versus Openai: AI berjuang untuk pelajarGoogle Versus Openai: AI berjuang untuk pelajarApr 18, 2025 am 11:31 AM

Impak segera berbanding perkongsian jangka panjang? Dua minggu yang lalu Openai melangkah ke hadapan dengan tawaran jangka pendek yang kuat, memberikan akses kepada pelajar A.S. dan Kanada.

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

Muat turun versi mac editor Atom

Muat turun versi mac editor Atom

Editor sumber terbuka yang paling popular

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa