Un examen que el modelo ya ha visto
Entrenamiento, validación y prueba son tres montones separados de ejemplos. El modelo aprende del primero, tú ajustas con el segundo y juzgas con el tercero.
Si un caso de prueba está también en el montón de entrenamiento, el modelo puede limitarse a recordarlo. La nota parece buena y no significa nada.
Al final de esta lección
Nota
Puedo mantener los casos de prueba fuera de los datos de entrenamiento.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Conjunto de entrenamiento | los ejemplos de los que aprende el modelo |
| Conjunto de validación | ejemplos que sirven para ajustar decisiones |
| Conjunto de prueba | ejemplos guardados para juzgar el resultado |
| Fuga | un caso de prueba que también está en el entrenamiento |
| Duplicado | un ejemplo que aparece dos veces |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Tres montones con tres trabajos
Divide tu archivo ya revisado antes de entrenar. La mayoría de los ejemplos van al conjunto de entrenamiento. Un montón menor, el conjunto de validación, te deja comparar opciones sobre la marcha. El conjunto de prueba se toca una vez, al final.
Divide con una regla fija, como la posición, para que las mismas filas caigan siempre en el mismo montón.
Ejemplo resuelto: diez filas, tres montones
| Montón | Filas | Para qué sirve |
|---|---|---|
| Entrenamiento | 1 a 6 | Aprender |
| Validación | 7 y 8 | Elegir entre versiones |
| Prueba | 9 y 10 | Un juicio final |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Una copia casi idéntica también es fuga
La fila 1 dice "Dónde está mi paquete". La fila 7 dice "¿Dónde está mi paquete?". Las palabras son las mismas, así que el modelo ya ha visto la respuesta.
Para cazarlas, deja primero los dos textos en forma simple. Pasa a minúsculas, quita los signos como ¿ y ? y reduce los espacios. Después compara.
Un error frecuente
Advertencia
Mucha gente cree que mezclar el archivo al azar protege el conjunto de prueba. Una mezcla reparte copias del mismo ejemplo en montones distintos. Quita primero los duplicados y divide después.
Escribe el ayudante del modelo, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el ayudante del modelo, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' ' try {' ' const res = await fetch(base + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"estado \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' ' } catch (error) {' ' console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el buscador de fugas, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const rows = [' ' \"Dónde está mi paquete\", \"Me cobraron dos veces\", \"Quiero cancelar mi pedido\",' ' \"La caja llegó aplastada\", \"El importe de la factura es erróneo\", \"¿Puedo cambiar mi dirección?\",' ' \"¿Dónde está mi paquete?\", \"Me encanta vuestra tienda\", \"Mi devolución no ha llegado\", \"¿Abrís el domingo?\",' '];' > adapt3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el buscador de fugas, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function normal(text) {' ' let out = \"\";' ' for (const ch of text.toLowerCase()) {' ' if (/[\p{L}\p{N} ]/u.test(ch)) out = out + ch;' ' }' ' return out.split(\" \").filter(function (w) { return w.length > 0; }).join(\" \");' '}' 'const train = rows.slice(0, 6);' 'const validation = rows.slice(6, 8);' 'const test = rows.slice(8);' >> adapt3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el buscador de fugas, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function leaks(from, into) {' ' const seen = from.map(normal);' ' return into.filter(function (t) { return seen.includes(normal(t)); });' '}' 'async function main() {' ' console.log(\"entrenamiento \" + train.length + \", validación \" + validation.length + \", prueba \" + test.length);' ' console.log(\"fugas a validación: \" + leaks(train, validation).join(\" | \"));' ' console.log(\"fugas a prueba: \" + leaks(train, test).length);' ' const q = \"En una frase, ¿por qué un caso de prueba nunca debe aparecer en los datos de entrenamiento?\";' ' const sample = \"Un modelo puede repetir un ejemplo que ya vio, así que un caso de prueba colado hace que la nota parezca mejor de lo que es.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 40);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> adapt3.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta el buscador de fugas
docker exec -w /home/node/project agent node adapt3.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo que informó el buscador
El Run reparte diez frases inventadas por posición y compara el texto simple de cada una. Encuentra una fuga hacia validación y ninguna hacia prueba.
La última línea es una llamada corta al modelo, o una Muestra grabada.